home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FM Towns: Free Software Collection 4
/
FM Towns Free Software Collection 4 - Disc 1.iso
/
pao
/
towns
/
cdplay
/
src
/
cdda.c
next >
Wrap
C/C++ Source or Header
|
1991-10-18
|
103KB
|
2,808 lines
/* << High C V1.4 >> **********************************************************
**
** CD演奏ライブラリ
**
** 1991.02.09 : CREATE
** 1991.02.13 : FINISH
**
** < HISTORY >
** 1991.02.09 : CREATE
** 1991.02.19 : SHUFFLE機能の追加.
** 1991.02.27 : 全面改訂開始....
** 1991.03.23 : 全面改訂終了(新ライブラリ誕生)
** 1991.03.25 : PROGRAM演奏モードままCDを入れ換えた時に、未選択合計時間
** の値がおかしくなるのを修正. (tocread()内で設定するよう変更)
** 1991.03.29 : PROGRAM演奏モード時に最後の演奏曲を演奏中に削除した時に、登録
** 曲を全てクリアしていたのを仕様変更し、リピート設定がなければ クリア
** するようにした.
** 1991.03.31 : 演奏できなかった時に、NOT READY にしていたのを パラメタエラー に
** なるよう修正した.
** 1991.04.19 : 初期処理時に演奏中だった場合にTOC情報取得後の演奏開始時間が
** 曲の先頭になっていたのを続きの時間になるよう修正.
** 1991.06.07 : 清書
**
** < note > : TABS = 4
**
** All Rights Reserved, Copyright (C) Y.Hirata 1991.
**
** Programmed by Y.Hirata ( Nifty ID : NAB03321 )
**
******************************************************************************/
pragma Off (Floating_point) ;
#define _CDDA_LIB
#include <cdr.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "cdda.h"
char *COPYRIGHT = "CDDA LIBRARY v1.00 1991.06.07 Copyright (C) Y.Hirata 1991. " ;
/*-----------------------------------------------------------------------------
** CDDA.LIB 解説
**
** 主な関数では、初期化ルーチンが呼ばれたかどうかチェックし、必ず呼ぶようにしてます.
**
** 演奏曲は、すべて CDDA_PLAY_no[] と そのポインタ CDDA_nplay によって管理して
** います. また、演奏開始時にはほとんどノーチェックなので、STOP時やエラー時にクリア作業
** をするようにしてます.
**
** ステータス情報は、定期的に取得されることを大前提としています. CDDA_status() を
** 呼ぶということ.
-----------------------------------------------------------------------------*/
char CDDA_FLG_libinit = CDDA_FALSE ; /* 初期化処理をしたか? */
char CDDA_FLG_tocread = CDDA_FALSE ; /* TOC情報を取得しているか? */
char CDDA_FLG_pause = CDDA_FALSE ; /* 一時停止中か? */
char CDDA_FLG_change = CDDA_FALSE ; /* CDの入れ換えがあったか? */
char CDDA_FLG_repeat = CDDA_FALSE ; /* リピート演奏するのか? */
char CDDA_FLG_pauseplay ; /* 演奏開始指定時間にPAUSE解除するか? */
char CDDA_FLG_shuffleinit ; /* シャッフル情報を初期化するのか? */
char CDDA_FLG_nowplay ; /* 現在演奏中か? */
char CDDA_FLG_cdstop ; /* CDの回転を停止したか? */
char CDDA_FLG_repeaton = CDDA_FALSE ; /* リピートを受け付けた? */
char CDDA_FLG_stop = CDDA_TRUE ; /* プログラム終了時にSTOPする? */
char CDDA_FLG_stchange ; /* ステータス変更ありか? */
char CDDA_FLG_ffrew = CDDA_FALSE ; /* FF/REW中か? */
char CDDA_FLG_ffrewpause = CDDA_FALSE ; /* FF/REWのためにPAUSEしたか? */
char CDDA_FLG_prgrepeat = CDDA_FALSE ; /* プログラム演奏の最後の曲を削除
後に再演奏をするのか? */
int CDDA_PLAY_no[CDDA_MAX_TRACK] ; /* 演奏用曲番号格納 */
int CDDA_nplay ; /* 次は↑の内何番目か? */
int CDDA_prgptr ; /* プログラム用ポインタ */
int CDDA_PLAY_mode = CDDA_SW_CONTINUE ; /* 現在の演奏モード */
/***************************** 演奏曲情報初期化 ****************************/
void CDDA_music_clear( void )
/*=============================================================================
** 演奏曲の管理情報をクリアする.
**
** < INPUT > : なし
** < OUTPUT > : なし
** < RETURN > : なし
=============================================================================*/
{
int c ;
for ( c=0; c<CDDA_MAX_TRACK; c++ ) {
CDDA_PLAY_no[c] = CDDA_ZERO ;
}
CDDA_nplay = CDDA_ZERO ;
CDDA_prgptr = CDDA_ZERO ;
CDDA_TOTAL_program = CDDA_ZERO ;
CDDA_COUNT_program = CDDA_ZERO ;
CDDA_REMAIN_program = CDDA_ZERO ;
CDDA_TIME_program.min = CDDA_ZERO ;
CDDA_TIME_program.sec = CDDA_ZERO ;
CDDA_TIME_program.frame = CDDA_ZERO ;
memcpy( (char *)&CDDA_TIME_program2,(char *)&CDDA_TIME_music,
sizeof( CDDA_TRACK ) ) ;
CDDA_FLG_prgrepeat = CDDA_FALSE ;
}
/****************************** 各種情報初期化 *****************************/
void CDDA_libinit( void )
/*=============================================================================
** 各種データの初期化を行う.
**
** < INPUT > : なし
** < OUTPUT > : なし
** < RETURN > : なし
**
** 当ライブラリ内では必ず最初にこの関数をCALLして下さい.
=============================================================================*/
{
static char valflg = CDDA_FALSE ;
int c ;
if ( !valflg ) {
/* ↓↓ ★★ DEBUG ★★ ↓↓ */
if ( CDDA_DEBUG ) {
printf("\n<CDDA_libinit> CDDA Library start ...\n") ;
}
/* ↑↑ ★★ DEBUG ★★ ↑↑ */
CDDA_RANDINIT ; /* 乱数初期化 */
CDDA_INFO_buf.drv = 0 ; /* FMTOWNS CDドライブ番号 */
valflg = CDDA_TRUE ;
}
CDDA_NOW_start = CDDA_MIN_TRACK ;
CDDA_NOW_end = CDDA_MAX_TRACK ;
CDDA_NOW_status = CDDA_STAT_NOTREADY ;
CDDA_NOW_musicno = CDDA_ZERO ;
CDDA_FLG_tocread = CDDA_FALSE ;
CDDA_FLG_change = CDDA_FALSE ;
CDDA_FLG_pause = CDDA_FALSE ;
CDDA_FLG_pauseplay = CDDA_FALSE ;
CDDA_FLG_shuffleinit = CDDA_TRUE ;
CDDA_FLG_nowplay = CDDA_FALSE ;
CDDA_FLG_repeaton = CDDA_FALSE ;
CDDA_FLG_cdstop = CDDA_TRUE ;
CDDA_INFO_buf.start = CDDA_ZERO ;
CDDA_INFO_buf.end = CDDA_ZERO ;
CDDA_INFO_buf.discend.min = CDDA_ZERO ;
CDDA_INFO_buf.discend.sec = CDDA_ZERO ;
CDDA_INFO_buf.discend.frame = CDDA_ZERO ;
CDDA_music_clear() ; /* 曲管理情報クリア */
/*-----------------------------------------------------------------------------
** シャッフルモードでは、CONTINUEモードに移行する.
-----------------------------------------------------------------------------*/
if ( CDDA_PLAY_mode == CDDA_SW_SHUFFLE )
CDDA_PLAY_mode = CDDA_SW_CONTINUE ;
for ( c=0; c<CDDA_MAX_TRACK; c++ ) {
memcpy( (char *)&CDDA_INFO_buf.track[c],(char *)&CDDA_INFO_buf.discend,
sizeof( CDDA_TRACK ) ) ;
memcpy( (char *)&CDDA_TIME_track[c],(char *)&CDDA_INFO_buf.discend,
sizeof( CDDA_TRACK ) ) ;
}
memcpy( (char *)&CDDA_TIME_music,(char *)&CDDA_INFO_buf.discend,
sizeof( CDDA_TRACK ) ) ;
memcpy( (char *)&CDDA_TIME_data,(char *)&CDDA_INFO_buf.discend,
sizeof( CDDA_TRACK ) ) ;
memcpy( (char *)&CDDA_CLOCK_nowtrack,(char *)&CDDA_INFO_buf.discend,
sizeof( CDDA_TRACK ) ) ;
memcpy( (char *)&CDDA_CLOCK_nowdisc,(char *)&CDDA_INFO_buf.discend,
sizeof( CDDA_TRACK ) ) ;
memcpy( (char *)&CDDA_TIME_nowtrack,(char *)&CDDA_INFO_buf.discend,
sizeof( CDDA_TRACK ) ) ;
memcpy( (char *)&CDDA_TIME_nowdisc,(char *)&CDDA_INFO_buf.discend,
sizeof( CDDA_TRACK ) ) ;
memcpy( (char *)&CDDA_CLOCK_program,(char *)&CDDA_INFO_buf.discend,
sizeof( CDDA_TRACK ) ) ;
CDDA_FLG_libinit = CDDA_TRUE ;
}
/****************************** CD情報の取得 *****************************/
int CDDA_cdinfo( void )
/*=============================================================================
** CD情報取得命令を発行する.
**
** < INPUT > : なし
** < OUTPUT > : なし
** < RETURN > : エラー値
**
** この関数にてCD情報を取得する際には、必ず数回のリトライを行って下さい.
=============================================================================*/
{
if ( !CDDA_FLG_libinit ) CDDA_libinit() ;
return(
cdr_cdinfo(
CDDA_INFO_buf.drv,&CDDA_INFO_buf.type,
&CDDA_INFO_buf.start,&CDDA_INFO_buf.end,
(char *)CDDA_INFO_buf.track,(char *)&CDDA_INFO_buf.discend
)
) ;
}
/**************************** TOC情報の取得 *****************************/
int CDDA_tocread( void )
/*=============================================================================
** TOC情報を取得する.
**
** < INPUT > : なし
** < OUTPUT > : なし
** < RETURN > : = 偽 - TOC 読み込み成功(エラーなし)
** 真 - TOC 読み込み失敗(エラーあり)
=============================================================================*/
{
int errcnt, ret ;
int c ;
/*
** 共通フラグの初期化
*/
CDDA_libinit() ;
/*
** CD 回転停止時間を連続回転に設定
*/
cdr_pause( CDDA_INFO_buf.drv ) ;
cdr_stptime( CDDA_INFO_buf.drv,CDDA_ZERO ) ;
/*
** TOC 読み込み
*/
/*-----------------------------------------------------------------------------
** TOC 取得時には、CD の回転が安定するまでの間 エラー となるので、必ず リトライ
** 処理をする必要がある.
-----------------------------------------------------------------------------*/
errcnt = CDDA_ZERO ;
do {
ret = CDDA_cdinfo() ;
cdr_pause( CDDA_INFO_buf.drv ) ;
errcnt++ ;
} while ( ret && errcnt<=CDDA_RETRY ) ;
if ( errcnt > CDDA_RETRY ) { /* TOC 読み込み失敗! */
CDDA_libinit() ;
/* ↓↓ ★★ DEBUG ★★ ↓↓ */
if ( CDDA_DEBUG ) {
printf("\n<CDDA_tocread> TOC read NG!!!\n") ;
}
/* ↑↑ ★★ DEBUG ★★ ↑↑ */
return( CDDA_ERR_NOTREADY ) ;
} else { /* TOC 読み込み成功♪ */
CDDA_FLG_tocread = CDDA_TRUE ;
CDDA_NOW_status = CDDA_STAT_STOP ;
/*-----------------------------------------------------------------------------
** 各曲の演奏時間および データ部分,音楽部分の合計時間を求める.
-----------------------------------------------------------------------------*/
CDDA_timecalc() ;
memcpy( (char *)&CDDA_TIME_program2,(char *)&CDDA_TIME_music,
sizeof( CDDA_TRACK ) ) ;
/*-----------------------------------------------------------------------------
** 演奏曲の番号を保持する.
** シャッフルモードでは、CONTINUEモードに移行する.
** プログラムモード については、演奏曲を クリア しておく.
-----------------------------------------------------------------------------*/
switch ( CDDA_PLAY_mode ) {
case CDDA_SW_SHUFFLE :
CDDA_PLAY_mode = CDDA_SW_CONTINUE ;
case CDDA_SW_CONTINUE :
case CDDA_SW_SINGLE :
for ( c=0; c<CDDA_INFO_buf.end; c++ )
CDDA_PLAY_no[c] = c+1 ;
break ;
case CDDA_SW_PROGRAM :
break ;
}
/* ↓↓ ★★ DEBUG ★★ ↓↓ */
if ( CDDA_DEBUG ) {
printf( "\n<CDDA_tocread> TOC read OK!\n" ) ;
for ( c=0; c<CDDA_INFO_buf.end; c++ ) {
printf( "%02d : %2d-%02d-%02d ; ",c+1,CDDA_TIME_track[c].min,
CDDA_TIME_track[c].sec,CDDA_TIME_track[c].frame ) ;
if ( CDDA_data_check( c+1 ) ) printf( "データ\n" ) ;
else printf( "音楽\n" ) ;
}
printf( "\n" ) ;
}
/* ↑↑ ★★ DEBUG ★★ ↑↑ */
return( CDDA_ERR_NOERROR ) ;
}
}
/********************************* CDシーク *********************************/
int CDDA_seek( void )
/*=============================================================================
** CD の ヘッド を演奏開始位置に移動する.
**
** < INPUT > : なし
** < OUTPUT > : なし
** < RETURN > : エラー値
**
** CDDA_CLOCK_start を設定してからこの関数をCALLすること.
=============================================================================*/
{
if ( !CDDA_FLG_libinit ) CDDA_libinit() ;
/*
** CDDA のないコンパクトディスクには用がない!
*/
if ( CDDA_INFO_buf.type != CDDA_TYPE_CDDA &&
CDDA_INFO_buf.type != CDDA_TYPE_BOTH ) return( CDDA_ERR_NOMUSIC ) ;
if ( CDDA_NOW_status == CDDA_STAT_NOTREADY ) return( CDDA_ERR_NOTREADY ) ;
if ( CDDA_NOW_status == CDDA_STAT_PLAY ) return( CDDA_ERR_NOWPLAY ) ;
return(
cdr_tseek( CDDA_INFO_buf.drv,(char *)&CDDA_CLOCK_start )
) ;
}
/******************************* CD演奏 **********************************/
int CDDA_mtrplay( void )
/*=============================================================================
** CD演奏命令を発行する.
**
** < INPUT > : なし
** < OUTPUT > : なし
** < RETURN > : エラー値
**
** CDDA_CLOCK_start および CDDA_CLOCK_end を設定してからこの関数をCALLする
** こと.
=============================================================================*/
{
int rep, st ;
if ( !CDDA_FLG_libinit ) CDDA_libinit() ;
/*
** CDDA のないコンパクトディスクには用がない!
*/
if ( CDDA_INFO_buf.type != CDDA_TYPE_CDDA &&
CDDA_INFO_buf.type != CDDA_TYPE_BOTH ) return( CDDA_ERR_NOMUSIC ) ;
/*-----------------------------------------------------------------------------
** CONTINUEモードで最初から最後までをリピートありで演奏する時だけ、繰り返し演奏
** 命令を発行する. それ以外は、一回だけの演奏とする.
**
** 各演奏モードは、演奏終了したかどうかのチェックなどを行う時に、繰り返し演奏さ
** れていないことを前提としている.
-----------------------------------------------------------------------------*/
rep = CDDA_MIN_REPEAT ;
st = CDDA_INFO_buf.start ;
if ( CDDA_INFO_buf.type == CDDA_TYPE_BOTH ) st ++ ;
if ( CDDA_FLG_repeaton && CDDA_PLAY_mode == CDDA_SW_CONTINUE &&
CDDA_NOW_start == st && CDDA_NOW_end == CDDA_INFO_buf.end &&
!CDDA_data_check( st ) ) {
rep = CDDA_MAX_REPEAT ;
}
return(
cdr_mtrplay(
CDDA_INFO_buf.drv,
(char *)&CDDA_CLOCK_start,(char *)&CDDA_CLOCK_end,rep
)
) ;
}
/************************* CDの演奏を停止します。 *************************/
void CDDA_stop( void )
/*=============================================================================
** CD演奏停止命令を発行する.
**
** < INPUT > : なし
** < OUTPUT > : なし
** < RETURN > : なし
=============================================================================*/
{
int errcnt, ret ;
if ( !CDDA_FLG_libinit ) CDDA_libinit() ;
/*-----------------------------------------------------------------------------
** CD が入れ換えられた後に初めて アクセス した時のことを考えて、停止処理も リトライ
** 処理を行う.
-----------------------------------------------------------------------------*/
errcnt = CDDA_ZERO ;
do {
ret = cdr_mstop( CDDA_INFO_buf.drv ) ;
errcnt++ ;
} while ( ret && errcnt<=CDDA_RETRY ) ;
/*-----------------------------------------------------------------------------
** 制御フラグクリア
-----------------------------------------------------------------------------*/
CDDA_NOW_status = CDDA_STAT_STOP ;
CDDA_NOW_musicno = CDDA_ZERO ;
CDDA_NOW_pause = CDDA_ZERO ;
CDDA_FLG_pause = CDDA_FALSE ;
CDDA_FLG_pauseplay = CDDA_FALSE ;
CDDA_FLG_shuffleinit = CDDA_TRUE ;
CDDA_FLG_cdstop = CDDA_TRUE ;
CDDA_FLG_repeaton = CDDA_FALSE ;
/*-----------------------------------------------------------------------------
** プログラムモード時には、演奏曲を示すポインタをクリアしてしまうと、いったんSTOPして
** 途中からPLAYした時にプログラム設定された最初の曲(既に演奏終了したものを含)
** から演奏してしまうことになる.
**
** プログラムモード時のポインタクリアは、STOPキー(本ライブラリに対してSTOP命令を発行する)の
** 指定があった時に行う.
-----------------------------------------------------------------------------*/
if ( CDDA_PLAY_mode != CDDA_SW_PROGRAM ) {
CDDA_nplay = CDDA_ZERO ;
CDDA_prgptr = CDDA_ZERO ;
}
}
/*************************** CD演奏状態の取得 ****************************/
int CDDA_mphase( void )
/*=============================================================================
** CD演奏状態取得命令を発行する.
**
** < INPUT > : なし
** < OUTPUT > : なし
** < RETURN > : エラー値
=============================================================================*/
{
if ( !CDDA_FLG_libinit ) CDDA_libinit() ;
return(
cdr_mphase(
CDDA_INFO_buf.drv,&CDDA_NOW_status,&CDDA_NOW_musicno,
(char *)&CDDA_CLOCK_nowtrack,(char *)&CDDA_CLOCK_nowdisc
)
) ;
}
/**************************** シャッフル演奏状態を監視 **************************/
int CDDA_shuffle_check( void )
/*=============================================================================
** シャッフル演奏状態のチェックを行う.
**
** < INPUT > : なし
** < OUTPUT > : なし
** < RETURN > : エラー値
**
** この関数は、演奏状態を取得後CALLして下さい.
=============================================================================*/
{
int ret ;
ret = CDDA_ERR_NOERROR ;
switch ( CDDA_NOW_status ) {
case CDDA_STAT_STOP :
/*-----------------------------------------------------------------------------
** シャッフルモードでは、全ての曲を終了するまでは STOP 状態ということはない.
** STOP状態ならば、シャッフル時の次の曲を調べて演奏をする.
-----------------------------------------------------------------------------*/
if ( CDDA_FLG_nowplay ) {
ret = CDDA_shuffle( &CDDA_NOW_start ) ;
if ( !ret ) {
CDDA_NOW_end = CDDA_NOW_start ;
CDDA_FLG_stchange = CDDA_TRUE ;
ret = CDDA_play() ;
} else {
/*-----------------------------------------------------------------------------
** シャッフルモード時に全ての曲を演奏終了していても、リピート指定があった時には再度
** シャッフル演奏を行う.
-----------------------------------------------------------------------------*/
if ( CDDA_FLG_repeaton ) {
/*-----------------------------------------------------------------------------
** シャッフルをし直すには、CDDA_FLG_shuffleinit を 真値 にして CDDA_shuffle()
** を CALL する.
-----------------------------------------------------------------------------*/
CDDA_FLG_shuffleinit = CDDA_TRUE ;
if ( !CDDA_shuffle( &CDDA_NOW_start ) ) {
CDDA_NOW_end = CDDA_NOW_start ;
CDDA_FLG_stchange = CDDA_TRUE ;
ret = CDDA_play() ;
if ( !ret ) ret = CDDA_ERR_REPEAT ;
} else {
/*-----------------------------------------------------------------------------
** シャッフルをし直しても次の曲番号がない時には、音楽のない CD だと判断する.
-----------------------------------------------------------------------------*/
ret = CDDA_ERR_NOMUSIC ;
}
} else {
/*-----------------------------------------------------------------------------
** 演奏終了 : CD の回転を停止させるため STOP する.
-----------------------------------------------------------------------------*/
if ( !CDDA_FLG_cdstop ) CDDA_stop() ;
CDDA_FLG_nowplay = CDDA_FALSE ;
ret = CDDA_ERR_NOERROR ;
}
}
} else {
/*-----------------------------------------------------------------------------
** 演奏終了 : CD の回転を停止させるため STOP する.
-----------------------------------------------------------------------------*/
if ( !CDDA_FLG_cdstop ) CDDA_stop() ;
CDDA_FLG_nowplay = CDDA_FALSE ;
}
break ;
case CDDA_STAT_PLAY :
/*-----------------------------------------------------------------------------
** シャッフル演奏時は、シングルと同じく一曲演奏なので、演奏開始曲と現在の演奏曲が
** 異なることはない.
** 異なった時には、演奏指定した次の曲に突入しているので、シャッフル用の次の曲
** を演奏する.
-----------------------------------------------------------------------------*/
if ( CDDA_NOW_musicno != CDDA_NOW_start ) {
ret = CDDA_shuffle( &CDDA_NOW_start ) ;
if ( !ret ) {
CDDA_NOW_end = CDDA_NOW_start ;
CDDA_FLG_stchange = CDDA_TRUE ;
ret = CDDA_play() ;
} else {
/*-----------------------------------------------------------------------------
** シャッフル用の次の曲がない時には、全ての曲の演奏を終了した時であるので、演奏
** を停止する(リピート指定のない時).
-----------------------------------------------------------------------------*/
if ( CDDA_FLG_repeaton ) {
/*-----------------------------------------------------------------------------
** シャッフルをし直すには、CDDA_FLG_shuffleinit を 真値 にして CDDA_shuffle()
** を CALL する.
-----------------------------------------------------------------------------*/
CDDA_FLG_shuffleinit = CDDA_TRUE ;
if ( !CDDA_shuffle( &CDDA_NOW_start ) ) {
CDDA_NOW_end = CDDA_NOW_start ;
CDDA_FLG_stchange = CDDA_TRUE ;
ret = CDDA_play() ;
if ( !ret ) ret = CDDA_ERR_REPEAT ;
} else {
/*-----------------------------------------------------------------------------
** シャッフルをし直しても次の曲番号がない時には、音楽のない CD だと判断する.
-----------------------------------------------------------------------------*/
ret = CDDA_ERR_NOMUSIC ;
}
} else {
CDDA_FLG_stchange = CDDA_TRUE ;
CDDA_stop() ;
CDDA_FLG_nowplay = CDDA_FALSE ;
ret = CDDA_ERR_NOERROR ;
}
}
}
break ;
}
return( ret ) ;
}
/*************************** プログラム演奏状態を監視 *************************/
void CDDA_program_playend( void )
/*=============================================================================
** プログラム演奏の終了.
**
** < INPUT > : なし
** < OUTPUT > : なし
** < RETURN > : なし
**
** この関数は、CDDA_program_check() から呼ばれる.
=============================================================================*/
{
if ( CDDA_NOW_status != CDDA_STAT_STOP ) CDDA_FLG_stchange = CDDA_TRUE ;
if ( !CDDA_FLG_cdstop ) {
CDDA_stop() ;
CDDA_music_clear() ; /* 曲管理情報クリア */
}
CDDA_FLG_nowplay = CDDA_FALSE ;
}
/*************************** プログラム演奏状態を監視 *************************/
int CDDA_program_check( void )
/*=============================================================================
** プログラム演奏状態のチェックを行う.
**
** < INPUT > : なし
** < OUTPUT > : なし
** < RETURN > : エラー値
**
** この関数は、演奏状態を取得後CALLして下さい.
=============================================================================*/
{
int ret ;
int no ;
ret = CDDA_ERR_NOERROR ;
switch ( CDDA_NOW_status ) {
case CDDA_STAT_STOP :
case CDDA_STAT_PAUSE :
/*-----------------------------------------------------------------------------
** プログラムモードには、演奏曲を全て演奏していないのに停止している時がある.
** (曲番号指定時とか確認時など)
**
** そのために、利用者が STOP 状態としているのならば、次の曲を処理しないよう
** にする. そのために CDDA_FLG_nowplay が 真値 か 偽値 かどうかで判断する.
**
** CDDA_FLG_nowplay は、演奏指示があった時に 真値とし、演奏中に STOP した
** 時または演奏指示が出ていない時には、偽値とする. この フラグ 操作は、キー
** 入力時(本ライブラリに対しスイッチ指定ありの時)とする.
**
** プログラム登録曲の最後の曲がPAUSE中に削除された時には、リピートなしならば停止
** 処理をし、リピートありならば演奏開始時間の設定だけを行っておく.
** CDDA_program_data_clear()にて、演奏中の曲を削除した時に リピート 演奏に入っ
** たことを知らせるために、ここでその処理を行う.
-----------------------------------------------------------------------------*/
if ( CDDA_NOW_status == CDDA_STAT_PAUSE && !CDDA_FLG_prgrepeat )
return( ret ) ;
if ( CDDA_FLG_nowplay || CDDA_FLG_prgrepeat ) {
if ( CDDA_FLG_prgrepeat ) {
CDDA_nplay = CDDA_ZERO ;
if ( CDDA_NOW_status == CDDA_STAT_PAUSE ) {
if ( !CDDA_ffmusic() ) {
CDDA_FLG_stchange = CDDA_TRUE ;
CDDA_REMAIN_program = CDDA_TOTAL_program ;
ret = CDDA_ERR_REPEAT ;
} else {
CDDA_program_playend() ;
}
} else {
if ( !CDDA_next_music() ) {
CDDA_FLG_stchange = CDDA_TRUE ;
CDDA_REMAIN_program = CDDA_TOTAL_program ;
ret = CDDA_play() ;
if ( !ret ) ret = CDDA_ERR_REPEAT ;
} else {
CDDA_program_playend() ;
}
}
CDDA_FLG_prgrepeat = CDDA_FALSE ;
} else if ( !CDDA_next_music() ) {
CDDA_FLG_stchange = CDDA_TRUE ;
ret = CDDA_play() ;
} else {
/*-----------------------------------------------------------------------------
** 次の曲がなければ、リピート指定ありかどうかチェックし、リピート指定ありならば、プロ
** グラム指定された最初の曲から演奏する. (リプレイ)
-----------------------------------------------------------------------------*/
if ( CDDA_FLG_repeaton ) {
CDDA_nplay = CDDA_ZERO ;
if ( !CDDA_next_music() ) {
CDDA_FLG_stchange = CDDA_TRUE ;
CDDA_REMAIN_program = CDDA_TOTAL_program ;
ret = CDDA_play() ;
if ( !ret ) ret = CDDA_ERR_REPEAT ;
} else {
/*-----------------------------------------------------------------------------
** 次の曲(最初の曲)がない時には、演奏終了.
-----------------------------------------------------------------------------*/
CDDA_program_playend() ;
}
} else {
/*-----------------------------------------------------------------------------
** 演奏終了 : CD の回転を停止させるため STOP する.
** 何もしないで、演奏が終了したならば、プログラム曲を全て クリア する.
-----------------------------------------------------------------------------*/
CDDA_program_playend() ;
}
}
} else {
/*-----------------------------------------------------------------------------
** 演奏終了 : CD の回転を停止させるため STOP する.
-----------------------------------------------------------------------------*/
CDDA_program_playend() ;
}
break ;
case CDDA_STAT_PLAY :
/*-----------------------------------------------------------------------------
** プログラムモード時は、シングルと同じく一曲演奏なので、今演奏中の曲と演奏中で
** あるべき曲とが異なることはない. その時には、演奏指定した次の曲に突入
** しているので、プログラム指定された次の曲を演奏する.
** ただし、CDDA_NOW_musicno が 0 以下の時は プログラム曲確認中などにあり得る
** ので、その場合は チェック からはずす.
**
** 演奏中であるべきの曲は、CDDA_PLAY_no[] とその ポインタ CDDA_nplay により
** 求める.
-----------------------------------------------------------------------------*/
if ( CDDA_NOW_musicno <= CDDA_ZERO ) break ;
if ( CDDA_nplay > CDDA_ZERO ) {
no = CDDA_PLAY_no[CDDA_nplay-1] ;
} else {
no = CDDA_PLAY_no[CDDA_ZERO] ;
}
/*-----------------------------------------------------------------------------
** 演奏中であるべき曲の次の曲を演奏していた時は、次のプログラム曲を演奏する.
-----------------------------------------------------------------------------*/
if ( CDDA_NOW_musicno == (no+1) ) {
if ( !CDDA_next_music() ) {
CDDA_FLG_stchange = CDDA_TRUE ;
ret = CDDA_play() ;
} else {
/*-----------------------------------------------------------------------------
** プログラム指定された次の曲がない時には、全ての曲の演奏を終了した時であるの
** で、演奏を停止する(リピート指定のない時).
-----------------------------------------------------------------------------*/
if ( CDDA_FLG_repeaton ) {
CDDA_nplay = CDDA_ZERO ;
if ( !CDDA_next_music() ) {
CDDA_FLG_stchange = CDDA_TRUE ;
CDDA_REMAIN_program = CDDA_TOTAL_program ;
ret = CDDA_play() ;
if ( !ret ) ret = CDDA_ERR_REPEAT ;
} else {
/*-----------------------------------------------------------------------------
** 次の曲(最初の曲)がない時には、演奏終了.
-----------------------------------------------------------------------------*/
CDDA_FLG_stchange = CDDA_TRUE ;
CDDA_program_playend() ;
}
} else {
/*-----------------------------------------------------------------------------
** 停止時には、全ての曲を終了したことにするために フラグ と ポインタ を クリア する.
-----------------------------------------------------------------------------*/
CDDA_program_playend() ;
}
}
}
break ;
}
return( ret ) ;
}
/**************************** 全曲演奏状態を監視 ***************************/
int CDDA_continue_check( int musicno )
/*=============================================================================
** 全曲演奏モード時の演奏状態のチェックを行う.
**
** < INPUT > : なし
** < OUTPUT > : なし
** < RETURN > : エラー値
**
** この関数は、演奏状態を取得後CALLして下さい.
=============================================================================*/
{
int ret ;
int st ;
ret = CDDA_ERR_NOERROR ;
switch ( CDDA_NOW_status ) {
case CDDA_STAT_STOP :
if ( CDDA_NOW_end < CDDA_INFO_buf.end && CDDA_FLG_nowplay ) {
/*-----------------------------------------------------------------------------
** CONTINUEモード時は、最後の曲まで演奏していないのに停止していることはない.
** その時は、他のモードから移行してきた時であるので、最終曲まで演奏しているか
** どうかで判断し、終了した曲の次の曲から最後の曲までを演奏する.
-----------------------------------------------------------------------------*/
CDDA_NOW_start = CDDA_NOW_end + 1 ;
CDDA_NOW_end = CDDA_INFO_buf.end ;
CDDA_nplay = CDDA_NOW_start ;
CDDA_FLG_stchange = CDDA_TRUE ;
ret = CDDA_play() ;
} else {
if ( CDDA_FLG_repeaton ) {
/*-----------------------------------------------------------------------------
** リピート指定されていて最後の曲まで演奏し終わって、停止していた時には、最初
** から最後の曲までを演奏する.
-----------------------------------------------------------------------------*/
CDDA_nplay = CDDA_ZERO ;
CDDA_NOW_start = CDDA_INFO_buf.start ;
CDDA_NOW_end = CDDA_INFO_buf.end ;
CDDA_FLG_stchange = CDDA_TRUE ;
ret = CDDA_play() ;
if ( !ret ) ret = CDDA_ERR_REPEAT ;
} else {
/*-----------------------------------------------------------------------------
** 演奏終了 : CD の回転を停止させるため STOP する.
-----------------------------------------------------------------------------*/
if ( !CDDA_FLG_cdstop ) CDDA_stop() ;
CDDA_FLG_nowplay = CDDA_FALSE ;
}
}
break ;
case CDDA_STAT_PLAY :
if ( musicno != CDDA_NOW_musicno && musicno ) {
/*-----------------------------------------------------------------------------
** 演奏曲が変わった時に、その曲が音楽であるかどうかを チェック する.
** 音楽でなく データ である場合には、その次の曲(音楽)から演奏をする.
** また、指定されていた終了曲よりもあとの曲になった場合も同様である.
** (惰性で次の曲に突入してしまった場合のこと)
-----------------------------------------------------------------------------*/
if ( CDDA_NOW_musicno <= CDDA_ZERO ) break ;
if ( CDDA_NOW_musicno > CDDA_NOW_end ) {
/*-----------------------------------------------------------------------------
** CDDA_NOW_musicno が行き過ぎた曲の時に、ステータス取得時に演奏中であれば、演奏
** ポインタ が行き過ぎた曲に合わせられてしまう. そこで正しい位置に ポインタ を
** 設定し直す.
-----------------------------------------------------------------------------*/
CDDA_nplay = musicno ;
}
if ( CDDA_data_check( CDDA_NOW_musicno ) || /* データ */
CDDA_NOW_musicno > CDDA_NOW_end ) { /* 次の曲に突入 */
CDDA_FLG_stchange = CDDA_TRUE ;
if ( !CDDA_next_music() ) {
ret = CDDA_play() ;
} else {
if ( CDDA_FLG_repeaton ) {
/*-----------------------------------------------------------------------------
** リピート指定されていて最後の曲まで演奏し終わって、停止していた時には、最初
** から最後の曲までを演奏する.
-----------------------------------------------------------------------------*/
CDDA_nplay = CDDA_ZERO ;
CDDA_NOW_start = CDDA_INFO_buf.start ;
CDDA_NOW_end = CDDA_INFO_buf.end ;
ret = CDDA_play() ;
if ( !ret ) ret = CDDA_ERR_REPEAT ;
} else {
CDDA_stop() ;
CDDA_FLG_nowplay = CDDA_FALSE ;
ret = CDDA_ERR_NOERROR ;
}
}
}
/*-----------------------------------------------------------------------------
** 繰り返し演奏時のチェックをする.
-----------------------------------------------------------------------------*/
st = CDDA_INFO_buf.start ;
if ( CDDA_INFO_buf.type == CDDA_TYPE_BOTH ) st ++ ;
if ( CDDA_FLG_repeaton && CDDA_NOW_start == st &&
CDDA_NOW_end == CDDA_INFO_buf.end &&
!CDDA_data_check( st ) ) {
if ( musicno == CDDA_NOW_end && CDDA_NOW_musicno == st )
ret = CDDA_ERR_REPEAT ;
}
}
break ;
}
return( ret ) ;
}
/**************************** 一曲演奏状態を監視 ***************************/
int CDDA_single_check( int mode )
/*=============================================================================
** 一曲演奏モード時の演奏状態のチェックを行う.
**
** < INPUT > : 前回の演奏モード
** < OUTPUT > : なし
** < RETURN > : エラー値
**
** この関数は、演奏状態を取得後CALLして下さい.
=============================================================================*/
{
int ret ;
ret = CDDA_ERR_NOERROR ;
switch ( CDDA_NOW_status ) {
case CDDA_STAT_STOP :
/*-----------------------------------------------------------------------------
** シングルモード時は、リピート指定がない限り停止していても良い.
** リピート指定がある時には、再度演奏を開始する.
**
** ここでは、次の曲/前の曲という指定の仕方ではないため、ポインタ をここで設定
** しておく必要がある.
-----------------------------------------------------------------------------*/
if ( CDDA_FLG_repeaton ) {
CDDA_NOW_end = CDDA_NOW_start ;
CDDA_nplay = CDDA_NOW_start ;
CDDA_FLG_stchange = CDDA_TRUE ;
ret = CDDA_play() ;
if ( !ret ) ret = CDDA_ERR_REPEAT ;
} else {
/*-----------------------------------------------------------------------------
** 演奏終了 : CD の回転を停止させるため STOP する.
-----------------------------------------------------------------------------*/
if ( !CDDA_FLG_cdstop ) CDDA_stop() ;
CDDA_FLG_nowplay = CDDA_FALSE ;
}
break ;
case CDDA_STAT_PLAY :
/*-----------------------------------------------------------------------------
** シングルモード時に、演奏開始曲と現在の曲が異なることはない.
** 異なっている時には、演奏指定した曲の次の曲に突入しているので、演奏を停止
** する. ただし、リピート指定ありの時には、再度演奏指定されていた曲を演奏する.
-----------------------------------------------------------------------------*/
if ( mode == CDDA_PLAY_mode &&
CDDA_NOW_start != CDDA_NOW_musicno ) {
CDDA_FLG_stchange = CDDA_TRUE ;
if ( CDDA_FLG_repeaton ) {
CDDA_NOW_end = CDDA_NOW_start ;
CDDA_nplay = CDDA_NOW_start ;
ret = CDDA_play() ;
if ( !ret ) ret = CDDA_ERR_REPEAT ;
} else {
CDDA_stop() ;
CDDA_FLG_nowplay = CDDA_FALSE ;
ret = CDDA_ERR_NOERROR ;
}
}
break ;
}
return( ret ) ;
}
/************************ CDの現在の演奏状態を監視 ***********************/
int CDDA_play_check( void )
/*=============================================================================
** 演奏状態のチェックを行う.
**
** < INPUT > : なし
** < OUTPUT > : なし
** < RETURN > : エラー値
**
** この関数は、演奏状態を取得後CALLして下さい.
**
** この関数は、毎秒2~3回CALLするようにして下さい. そうしないと、演奏モード
** のとおりに演奏されません. また、演奏時間も保証されません.
=============================================================================*/
{
static int mode = CDDA_SW_CONTINUE ;
static int musicno = CDDA_ZERO ;
int ret ;
ret = CDDA_ERR_NOERROR ;
/*-----------------------------------------------------------------------------
** 各演奏モード毎に、今の演奏状態が妥当であるかどうかを チェック し、然るべき処理
** をとる.
-----------------------------------------------------------------------------*/
switch ( CDDA_PLAY_mode ) {
case CDDA_SW_SHUFFLE :
ret = CDDA_shuffle_check() ;
break ;
case CDDA_SW_PROGRAM :
ret = CDDA_program_check() ;
break ;
case CDDA_SW_CONTINUE :
ret = CDDA_continue_check( musicno ) ;
break ;
case CDDA_SW_SINGLE :
ret = CDDA_single_check( mode ) ;
break ;
}
/*-----------------------------------------------------------------------------
** 前回の演奏曲と演奏モードを保持しておく.
-----------------------------------------------------------------------------*/
mode = CDDA_PLAY_mode ;
musicno = CDDA_NOW_musicno ;
return( ret ) ;
}
/************************ CDの現在の演奏ポインタのチェック **********************/
void CDDA_nplay_check( void )
/*=============================================================================
** 演奏曲格納領域のポインタのチェックを行う.
**
** < INPUT > : なし
** < OUTPUT > : なし
** < RETURN > : なし
**
** この関数は、演奏状態を取得後CALLして下さい.
=============================================================================*/
{
int c ;
/*-----------------------------------------------------------------------------
** 演奏中でなければ、演奏曲が変わることがないので、ポインタ 操作不要である.
-----------------------------------------------------------------------------*/
if ( CDDA_NOW_status != CDDA_STAT_PLAY ) return ;
/*-----------------------------------------------------------------------------
** 演奏中にもかかわらず 次の曲を示す ポインタ が先頭を示していることはない.
** そのためにとりあえず インクリメント しておく.
-----------------------------------------------------------------------------*/
if ( CDDA_nplay <= CDDA_ZERO ) CDDA_nplay = 1 ;
switch ( CDDA_PLAY_mode ) {
case CDDA_SW_SHUFFLE :
case CDDA_SW_PROGRAM :
/*-----------------------------------------------------------------------------
** シャッフルモード, プログラムモード時には、演奏曲を示すのに きちんと ポインタ を使用して
** いるので、あらためて チェック する必要がない.
** 結構 チェック するのが、大変だったりするのですねぇ~.
-----------------------------------------------------------------------------*/
break ;
case CDDA_SW_CONTINUE :
case CDDA_SW_SINGLE :
/*-----------------------------------------------------------------------------
** シングルモード, CONTINUEモード時には、曲の順に正しく格納されているためと、演奏
** 開始時とかに ポインタ を必ずしも使用していないので、チェック しておく.
**
** ようするに、デフォルトでこのように曲を管理領域に格納しているので、このような
** 状況となっている. また、ポインタ も初期状態は クリア されているため.
-----------------------------------------------------------------------------*/
if ( CDDA_PLAY_no[CDDA_nplay-1] != CDDA_NOW_musicno ) {
for ( c=CDDA_nplay; c<CDDA_MAX_TRACK; c++ ) {
if ( CDDA_PLAY_no[c] == CDDA_NOW_musicno ) {
CDDA_nplay = c + 1 ;
break ;
}
}
}
break ;
}
}
/************************** CDの現在の状態を取得 *************************/
int CDDA_get_status( void )
/*=============================================================================
** 演奏状態の取得を行う.
**
** < INPUT > : なし
** < OUTPUT > : なし
** < RETURN > : エラー値
**
** この関数を続けてCALLする場合には、100ms以上待ち時間をおいて下さい.
** (この関数に限ったことではないのだが・・・・・)
** たてつづけにCALLすると、演奏中の場合には、音飛びなどの原因となります.
** 何故なんだろう?困ったもんだ・・・
**
** この関数は、毎秒2~3回CALLするようにして下さい. そうしないと、演奏モード
** のとおりに演奏されません. また、演奏時間も保証されません.
=============================================================================*/
{
int ret ;
if ( !CDDA_FLG_libinit ) CDDA_libinit() ;
CDDA_FLG_change = CDDA_FALSE ;
ret = CDDA_mphase() ;
if ( !ret ) {
if ( CDDA_NOW_status ) { /* 演奏中 */
/*-----------------------------------------------------------------------------
** 演奏中である旨を フラグ セット する.
** リピートフラグ は、停止中は無効で演奏に入った時点から有効とする.
** CDDA_FLG_repeat が真値の時 リピート 指定あり.
** CDDA_FLG_repeaton が真値の時 リピート有効 を表す.
-----------------------------------------------------------------------------*/
CDDA_FLG_nowplay = CDDA_TRUE ;
CDDA_FLG_cdstop = CDDA_FALSE ;
if ( CDDA_FLG_repeat ) CDDA_FLG_repeaton = CDDA_TRUE ;
CDDA_nplay_check() ;
CDDA_NOW_status = CDDA_STAT_PLAY ;
CDDA_remaintime() ; /* 残り時間取得 */
} else { /* 停止中 or PAUSE中 */
if ( CDDA_FLG_pause ) { /* 一時停止中 */
CDDA_FLG_nowplay = CDDA_TRUE ;
CDDA_FLG_cdstop = CDDA_FALSE ;
if ( CDDA_FLG_repeat ) CDDA_FLG_repeaton = CDDA_TRUE ;
CDDA_NOW_status = CDDA_STAT_PAUSE ;
/*-----------------------------------------------------------------------------
** PAUSE中は、演奏情報を変更しない. 元に戻しておく.
** PAUSE用の曲番号, 曲内経過時間は、FF/REW があれば変更される.
-----------------------------------------------------------------------------*/
CDDA_NOW_musicno = CDDA_NOW_pause ;
memcpy( (char *)&CDDA_CLOCK_nowtrack,
(char *)&CDDA_CLOCK_pause,
sizeof( CDDA_TRACK ) ) ;
} else { /* 停止中 */
/*-----------------------------------------------------------------------------
** 停止中を示すために各演奏状態を設定しておく.
** ただし、停止中というのは、一時的なものもあるので、各変数を停止した状態
** にしてはならない.
-----------------------------------------------------------------------------*/
CDDA_NOW_status = CDDA_STAT_STOP ;
CDDA_NOW_musicno = CDDA_ZERO ;
CDDA_NOW_pause = CDDA_ZERO ;
}
/* 残り時間 */
CDDA_remaintime() ;
}
return( CDDA_ERR_NOERROR ) ;
} else {
if ( ret == CDDA_ERR_CHANGE ) { /* CD が入れ換えられた */
CDDA_FLG_change = CDDA_TRUE ;
}
/*-----------------------------------------------------------------------------
** 演奏状態が取得できない時には、CD が セット されていないものと判断する.
-----------------------------------------------------------------------------*/
/* ↓↓ ★★ DEBUG ★★ ↓↓ */
if ( CDDA_DEBUG ) {
if ( ret == CDDA_ERR_NOTREADY ) {
printf("!") ;
} else {
printf("\n<CDDA_get_status> get_status return : ") ;
CDDA_debug_dispmsg( ret ) ;
}
}
/* ↑↑ ★★ DEBUG ★★ ↑↑ */
CDDA_libinit() ;
return( ret ) ;
}
}
/**************************** 演奏状態の取得とチェック *************************/
int CDDA_status( void )
/*=============================================================================
** 演奏状態の取得とチェックを行う.
**
** < INPUT > : なし
** < OUTPUT > : なし
** < RETURN > : エラー値
**
** この関数を続けてCALLする場合には、100ms以上待ち時間をおいて下さい.
** (この関数に限ったことではないのだが・・・・・)
** たてつづけにCALLすると、演奏中の場合には、音飛びなどの原因となります.
** 何故なんだろう?困ったもんだ・・・
**
** この関数は、毎秒2~3回CALLするようにして下さい. そうしないと、演奏モード
** のとおりに演奏されません. また、演奏時間も保証されません.
=============================================================================*/
{
int ret ;
/*-----------------------------------------------------------------------------
** 演奏状態を取得後に、各演奏モード毎に演奏状態が妥当かどうか チェック し、然る
** べき処理の後、演奏状態が変わることがあるために、再度演奏状態を取得する
** という アルゴリズム をとっている.
-----------------------------------------------------------------------------*/
ret = CDDA_get_status() ;
if ( ret ) {
/*-----------------------------------------------------------------------------
** ステータス情報取得は、必ず成功を前提とする. 失敗した時には、CD が抜かれたと
** みなす.
-----------------------------------------------------------------------------*/
/* ↓↓ ★★ DEBUG ★★ ↓↓ */
if ( CDDA_DEBUG ) {
if ( ret == CDDA_ERR_NOTREADY ) {
printf("!") ;
} else {
printf("\n<CDDA_status> get_status return : ") ;
CDDA_debug_dispmsg( ret ) ;
}
}
/* ↑↑ ★★ DEBUG ★★ ↑↑ */
CDDA_remaintime() ;
return( ret ) ;
}
CDDA_FLG_stchange = CDDA_FALSE ;
ret = CDDA_play_check() ;
if ( !CDDA_FLG_stchange ) {
/* ↓↓ ★★ DEBUG ★★ ↓↓ */
if ( CDDA_DEBUG ) {
if ( ret ) {
printf( "\n" ) ;
printf( "<CDDA_status> " ) ;
printf( "play_check return (not change status) : " ) ;
CDDA_debug_dispmsg( ret ) ;
printf( "\n" ) ;
}
}
/* ↑↑ ★★ DEBUG ★★ ↑↑ */
return( ret ) ;
}
if ( ret == CDDA_ERR_REPEAT ) return( ret ) ;
if ( ret && ret != CDDA_ERR_REPEAT ) {
/* ↓↓ ★★ DEBUG ★★ ↓↓ */
if ( CDDA_DEBUG ) {
printf( "\n<CDDA_status> play_check error return : " ) ;
CDDA_debug_dispmsg( ret ) ;
printf( "\n" ) ;
}
/* ↑↑ ★★ DEBUG ★★ ↑↑ */
CDDA_NOW_musicno = CDDA_ZERO ;
CDDA_NOW_pause = CDDA_ZERO ;
CDDA_nplay = CDDA_ZERO ;
CDDA_prgptr = CDDA_ZERO ;
CDDA_remaintime() ;
return( ret ) ;
}
/* ↓↓ ★★ DEBUG ★★ ↓↓ */
if ( CDDA_DEBUG ) {
printf( "\n" ) ;
printf( "<CDDA_status> " ) ;
printf( "play_check return (status change) : " ) ;
CDDA_debug_dispmsg( ret ) ;
printf( "\n" ) ;
}
/* ↑↑ ★★ DEBUG ★★ ↑↑ */
return( CDDA_get_status() ) ;
}
/**************************** 時間指定演奏処理 *****************************/
int CDDA_timeplay( void )
/*=============================================================================
** 指定された時間の範囲内を演奏する.
**
** < INPUT > : なし
** < OUTPUT > : なし
** < RETURN > : エラー値
**
** CDDA_CLOCK_start および CDDA_CLOCK_end を設定してからこの関数をCALLする
** こと.
=============================================================================*/
{
int errcnt ;
if ( !CDDA_FLG_libinit ) CDDA_libinit() ;
#if 0
/*
** PAUSE中に通常のPLAYは受け付けないようにする.
*/
if ( CDDA_FLG_pause && !CDDA_FLG_pauseplay ) return( CDDA_ERR_NOWPAUSE ) ;
#else
/*
** PLAYならばPAUSEは無条件に解除する.
*/
CDDA_FLG_pause = CDDA_FALSE ;
#endif
if ( !CDDA_FLG_tocread ) return( CDDA_ERR_NOTREADY ) ;
/* ↓↓ ★★ DEBUG ★★ ↓↓ */
if ( CDDA_DEBUG ) {
printf( "<CDDA_timeplay> " ) ;
printf( "start ~ end = %d ~ %d",
CDDA_NOW_start,CDDA_NOW_end ) ;
printf( " , start-time : %d.%d.%d\n",CDDA_CLOCK_start.min,
CDDA_CLOCK_start.sec,CDDA_CLOCK_start.frame ) ;
}
/* ↑↑ ★★ DEBUG ★★ ↑↑ */
/*-----------------------------------------------------------------------------
** CD の回転が安定するまでは、エラー となるので、リトライ 処理をしている.
-----------------------------------------------------------------------------*/
errcnt = 0 ;
do {
if ( cdr_pause( CDDA_INFO_buf.drv ) == CDDA_ERR_CHANGE ) {
CDDA_libinit() ;
CDDA_FLG_change = CDDA_TRUE ;
return( CDDA_ERR_CHANGE ) ;
}
if ( CDDA_mtrplay() == CDDA_ERR_PARAMETER ) { /* 演奏開始 */
return( CDDA_ERR_PARAMETER ) ;
}
if ( CDDA_mphase() ) CDDA_NOW_status = CDDA_STAT_STOP ;
if ( ++errcnt >= CDDA_RETRY ) {
/* ↓↓ ★★ DEBUG ★★ ↓↓ */
if ( CDDA_DEBUG ) {
printf("\n<CDDA_timeplay> NOT PLAY! retry count over.\n") ;
}
/* ↑↑ ★★ DEBUG ★★ ↑↑ */
return( CDDA_ERR_PARAMETER ) ;
}
} while( CDDA_NOW_status != CDDA_STAT_PLAY ) ;
/*-----------------------------------------------------------------------------
** 演奏処理をしたら、演奏状態を取得してその返り値を返す.
-----------------------------------------------------------------------------*/
return( CDDA_status() ) ;
}
/************************** CDの演奏をします。 ****************************/
int CDDA_play( void )
/*=============================================================================
** 指定された曲を演奏する.
**
** < INPUT > : なし
** < OUTPUT > : なし
** < RETURN > : エラー値
**
** CDDA_NOW_start および CDDA_NOW_end を設定してからこの関数をCALLすること.
**
** ここでは、演奏開始曲と演奏終了曲に従って演奏処理をするので、演奏中に演奏
** させない時などは、この関数を呼ぶ側で制御します.
**
** 時間指定による演奏などは、この関数を使用しないで、演奏開始/終了時間を設
** 定後 CDDA_timeplay() を CALL して下さい.
=============================================================================*/
{
if ( !CDDA_FLG_libinit ) CDDA_libinit() ;
/*
** TOC 読み込み
*/
if ( !CDDA_FLG_tocread ) {
if( CDDA_tocread() ) return( CDDA_ERR_NOTREADY ) ;
}
/*
** CDDA のないコンパクトディスクには用がない!
*/
if ( CDDA_INFO_buf.type != CDDA_TYPE_CDDA &&
CDDA_INFO_buf.type != CDDA_TYPE_BOTH ) return( CDDA_ERR_NOMUSIC ) ;
/*
** 演奏曲番号誤り
*/
if ( CDDA_NOW_start < CDDA_MIN_TRACK ) return( CDDA_ERR_PARAMETER ) ;
if ( CDDA_NOW_end > CDDA_MAX_TRACK ) return( CDDA_ERR_PARAMETER ) ;
if ( CDDA_NOW_start > CDDA_NOW_end ) return( CDDA_ERR_PARAMETER ) ;
if ( CDDA_NOW_start > CDDA_INFO_buf.end ||
CDDA_NOW_end < CDDA_INFO_buf.start )
return( CDDA_ERR_PARAMETER ) ;
/*
** 演奏時間設定
*/
CDDA_set_time_start( CDDA_NOW_start ) ; /* 演奏開始曲データ設定 */
CDDA_set_time_end( CDDA_NOW_end ) ; /* 演奏終了曲データ設定 */
/*
** 演奏開始
*/
return( CDDA_timeplay() ) ;
}
/************************* CD PAUSE/CONTINUE 処理 **************************/
int CDDA_pause( void )
/*=============================================================================
** 一時停止のON/OFFを行う.
**
** < INPUT > : なし
** < OUTPUT > : なし
** < RETURN > : エラー値
**
** CDDA_FLG_pause をこの関数以外で操作しないこと.
** また、当ライブラリ以外でCDのPAUSEやSTOPをしないこと.
=============================================================================*/
{
int ret ;
ret = CDDA_status() ; /* 演奏状態のチェック */
if ( ret ) return( ret ) ;
/*-----------------------------------------------------------------------------
** 停止中とPAUSE中を見分けるために、ライブラリ内の フラグ で管理しています.
** フラグ は、新たに演奏開始とか停止,エラーの場合などを除き、この関数内で制御し
** ます.
-----------------------------------------------------------------------------*/
if ( CDDA_NOW_status == CDDA_STAT_PAUSE ) { /* PAUSE中 */
CDDA_FLG_pause = CDDA_FALSE ;
/*-----------------------------------------------------------------------------
** PAUSE中に、別途指定した時間から演奏を開始する場合には、CDDA_FLG_pauseplay
** を呼ぶ側で 真値 にしておきます.
-----------------------------------------------------------------------------*/
if ( CDDA_FLG_pauseplay ) { /* 時間指定 PLAY */
ret = CDDA_timeplay() ;
if ( ret == CDDA_ERR_CHANGE ) { /* CD入れ換え時 */
CDDA_libinit() ;
CDDA_FLG_change = CDDA_TRUE ;
return( CDDA_ERR_CHANGE ) ;
} else if ( ret == CDDA_ERR_PARAMETER ) { /* パラメタエラー */
return( CDDA_ERR_PARAMETER ) ;
}
} else { /* CONTINUE */
if ( cdr_continue( CDDA_INFO_buf.drv ) == CDDA_ERR_CHANGE ) {
CDDA_libinit() ;
CDDA_FLG_change = CDDA_TRUE ;
return( CDDA_ERR_CHANGE ) ;
}
}
} else if ( CDDA_NOW_status == CDDA_STAT_PLAY ) { /* 演奏中 */
/*-----------------------------------------------------------------------------
** 演奏中ならばPAUSEする前に演奏時間を保存しておき、PAUSEする.
-----------------------------------------------------------------------------*/
ret = CDDA_status() ;
CDDA_FLG_pauseplay = CDDA_FALSE ;
if ( ret ) return( ret ) ;
CDDA_FLG_pause = CDDA_TRUE ;
CDDA_NOW_pause = CDDA_NOW_musicno ;
CDDA_NOW_start = CDDA_NOW_musicno ;
memcpy( (char *)&CDDA_CLOCK_pause,(char *)&CDDA_CLOCK_nowtrack,
sizeof( CDDA_TRACK ) ) ;
ret = cdr_pause( CDDA_INFO_buf.drv ) ;
if ( ret ) return( ret ) ;
} else if ( CDDA_NOW_status == CDDA_STAT_STOP ) { /* 停止中 */
/*-----------------------------------------------------------------------------
** 停止中ならば最初に演奏する曲の演奏情報だけを設定しておく.
-----------------------------------------------------------------------------*/
CDDA_FLG_pause = CDDA_TRUE ;
CDDA_FLG_pauseplay = CDDA_TRUE ;
if ( CDDA_nplay > CDDA_ZERO ) {
CDDA_NOW_start = CDDA_PLAY_no[CDDA_nplay-1] ;
CDDA_NOW_end = CDDA_PLAY_no[CDDA_nplay-1] ;
} else {
CDDA_NOW_start = CDDA_NOW_end = CDDA_PLAY_no[CDDA_ZERO] ;
}
if ( CDDA_NOW_start && CDDA_nplay == CDDA_ZERO ) CDDA_nplay ++ ;
CDDA_NOW_musicno = CDDA_NOW_pause = CDDA_NOW_start ;
CDDA_set_time_start( CDDA_NOW_start ) ; /* 演奏開始曲データ設定 */
CDDA_set_time_end( CDDA_NOW_end ) ; /* 演奏終了曲データ設定 */
CDDA_CLOCK_nowtrack.min = CDDA_ZERO ;
CDDA_CLOCK_nowtrack.sec = CDDA_ZERO ;
CDDA_CLOCK_nowtrack.frame = CDDA_ZERO ;
memcpy( (char *)&CDDA_CLOCK_pause,(char *)&CDDA_CLOCK_nowtrack,
sizeof( CDDA_TRACK ) ) ;
ret = cdr_pause( CDDA_INFO_buf.drv ) ;
if ( ret ) return( ret ) ;
} else { /* NOT READY */
CDDA_FLG_pause = CDDA_FALSE ;
CDDA_FLG_pauseplay = CDDA_FALSE ;
}
return( CDDA_status() ) ;
}
/****************************** シャッフルの初期化 *******************************/
void CDDA_shuffle_init( void )
/*=============================================================================
** シャッフルのための初期化を行う.
**
** < INPUT > : なし
** < OUTPUT > : なし
** < RETURN > : なし
**
** 乱数の初期化は、ライブラリの初期設定で行っておく.
=============================================================================*/
{
int c, cc ; /* ループカウンタ */
int music ; /* 乱数取得曲番号 */
int cnt ; /* 曲番号取得用(何番目か) */
char flg[CDDA_MAX_TRACK] ; /* 乱数取得曲番号用フラグ */
if ( !CDDA_FLG_tocread ) { /* TOC 読み込み */
if( CDDA_tocread() ) return ;
}
/*-----------------------------------------------------------------------------
** 初期化フラグをクリアするのは、ここだけである.
-----------------------------------------------------------------------------*/
CDDA_FLG_shuffleinit = CDDA_FALSE ; /* シャッフル初期化フラグクリア */
CDDA_music_clear() ; /* 曲管理情報クリア */
for ( c=0; c<CDDA_MAX_TRACK; c++ ) { /* フラグ初期化 */
flg[c] = CDDA_FALSE ;
}
/*-----------------------------------------------------------------------------
** 全ての曲を ランダム な順に演奏するように セット する.
-----------------------------------------------------------------------------*/
for ( c=CDDA_INFO_buf.end; c>0; c-- ) {
music = CDDA_RANDOM( c ) + 1 ;
cnt = 0 ;
for ( cc=0; cc<CDDA_INFO_buf.end; cc++ ) {
if ( !flg[cc] ) cnt ++ ;
if ( cnt == music ) {
flg[cc] = CDDA_TRUE ;
music = cc + 1 ;
break ;
}
}
CDDA_PLAY_no[CDDA_INFO_buf.end-c] = music ; /* 曲番号格納 */
}
}
/*************************** シャッフルの曲番号を返す ****************************/
int CDDA_shuffle( int *nextno )
/*=============================================================================
** シャッフルのための曲番号を取得する.
**
** < INPUT > : なし
** < OUTPUT > : 次の演奏曲番号, 終了時は 偽値.
** < RETURN > : エラー値
**
** この関数を最初に呼ぶ時には、必ず初期化フラグ(CDDA_FLG_shuffleinit)を真値に
** しておくこと.
=============================================================================*/
{
if ( !CDDA_FLG_libinit ) CDDA_libinit() ;
if ( CDDA_PLAY_mode != CDDA_SW_SHUFFLE ) return( CDDA_ERR_PARAMETER ) ;
*nextno = CDDA_ZERO ;
/*
** TOC 読み込み
*/
if ( !CDDA_FLG_tocread ) {
if( CDDA_tocread() ) return( CDDA_ERR_NOTREADY ) ;
/*
** CDDA のないコンパクトディスクには用がない!
*/
if ( CDDA_INFO_buf.type != CDDA_TYPE_CDDA &&
CDDA_INFO_buf.type != CDDA_TYPE_BOTH )
return( CDDA_ERR_NOMUSIC ) ;
}
/*
** シャッフル処理
*/
if ( CDDA_FLG_shuffleinit ) /* シャッフル情報初期化 */
CDDA_shuffle_init() ;
/*-----------------------------------------------------------------------------
** 次の曲を求める. 終了時には、曲番号が 0 で返り値が エラー値(真値)となる.
** 次の曲番号は、CDDA_NOW_start に セット されてくる.
-----------------------------------------------------------------------------*/
if ( CDDA_next_music() ) /* 全ての曲を終了した */
return( CDDA_ERR_PARAMETER ) ;
*nextno = CDDA_NOW_start ;
CDDA_NOW_pause = CDDA_NOW_musicno = CDDA_NOW_start ;
CDDA_CLOCK_nowtrack.min = CDDA_ZERO ;
CDDA_CLOCK_nowtrack.sec = CDDA_ZERO ;
CDDA_CLOCK_nowtrack.frame = CDDA_ZERO ;
memcpy( (char *)&CDDA_CLOCK_pause,(char *)&CDDA_CLOCK_nowtrack,
sizeof( CDDA_TRACK ) ) ;
return( CDDA_ERR_NOERROR ) ;
}
/************************** プログラムの曲番号を確認 ***************************/
int CDDA_program_data_check( void )
/*=============================================================================
** プログラムの曲番号を確認する.
**
** < INPUT > : なし
** < OUTPUT > : なし
** < RETURN > : 何曲目( 終了時は、0 : 最後の曲の場合には、-1 )
**
** 次の曲番号(確認したい曲番号)は、CDDA_NOW_musicno に セット します.
** プログラム登録曲数は、CDDA_TOTAL_program に セット されてます.
** 残り演奏曲数は、CDDA_REMAIN_program に セット されてます.
** 確認用の曲が何曲目 (演奏中または演奏開始曲を 1 として) かを
** CDDA_COUNT_program に セット します.
**
** 演奏ポインタ(CDDA_nplay), プログラムポインタ(CDDA_prgptr)の扱いに注意.
=============================================================================*/
{
CDDA_COUNT_program = CDDA_ZERO ;
if ( !CDDA_FLG_tocread ) return( CDDA_ZERO ) ;
if ( CDDA_PLAY_mode != CDDA_SW_PROGRAM ) return( CDDA_ZERO ) ;
/* ↓↓ ★★ DEBUG ★★ ↓↓ */
if ( CDDA_DEBUG ) {
printf( "<CDDA_program_data_check> " ) ;
printf( "prgptr = %d , nplay = %d , 登録曲数(残り) = %d(%d)\n",
CDDA_prgptr,CDDA_nplay,
CDDA_TOTAL_program,CDDA_REMAIN_program ) ;
}
/* ↑↑ ★★ DEBUG ★★ ↑↑ */
/*-----------------------------------------------------------------------------
** プログラムポインタ が クリア されている時には、今演奏中の曲番号の位置をスタート(0)と
** する. (通常は、クリア されているか 最後に曲を追加できるような位置になって
** いる.)
**
** アプリケーション側で、プログラム確認中にある程度時間がたったら、ポインタ を クリア する
** ようになっていることを想定している.
-----------------------------------------------------------------------------*/
if ( CDDA_prgptr == CDDA_ZERO ) {
CDDA_prgptr = CDDA_nplay ;
if ( CDDA_prgptr > CDDA_ZERO ) CDDA_prgptr -- ;
}
/*-----------------------------------------------------------------------------
** 最後の曲よりも後ろを ポインタ を指していた場合には、これで終わりだという意
* 味で、ポインタ を クリア し、曲番号には 0 を セット しておく.
-----------------------------------------------------------------------------*/
if ( CDDA_PLAY_no[CDDA_prgptr] == CDDA_ZERO ) {
/*
** 時間情報設定
*/
CDDA_NOW_musicno = CDDA_ZERO ;
CDDA_prgptr = CDDA_ZERO ;
CDDA_COUNT_program = CDDA_ZERO ;
CDDA_CLOCK_nowtrack.min = CDDA_ZERO ;
CDDA_CLOCK_nowtrack.sec = CDDA_ZERO ;
CDDA_CLOCK_nowtrack.frame = CDDA_ZERO ;
/* 残り時間計算 */
CDDA_program_remaintime() ;
return( CDDA_ZERO ) ;
} else {
/*-----------------------------------------------------------------------------
** プログラムポインタ を一つすすめる.
-----------------------------------------------------------------------------*/
CDDA_prgptr ++ ;
/*
** 時間情報設定
*/
CDDA_NOW_musicno = CDDA_PLAY_no[CDDA_prgptr-1] ;
/* プログラム設定合計時間 */
/*-----------------------------------------------------------------------------
** プログラムポインタ と 演奏ポインタ が等しく(プログラム確認した曲が現在演奏中の曲の時)
** て、現在 PAUSE状態の時には、PAUSEした時点までの時間が演奏済である.
-----------------------------------------------------------------------------*/
if ( CDDA_NOW_status == CDDA_STAT_PAUSE &&
CDDA_nplay == CDDA_prgptr ) {
memcpy( (char *)&CDDA_CLOCK_nowtrack,(char *)&CDDA_CLOCK_pause,
sizeof( CDDA_TRACK ) ) ;
} else {
CDDA_CLOCK_nowtrack.min = CDDA_ZERO ;
CDDA_CLOCK_nowtrack.sec = CDDA_ZERO ;
CDDA_CLOCK_nowtrack.frame = CDDA_ZERO ;
}
/* 残り時間計算 */
CDDA_program_remaintime() ;
/*-----------------------------------------------------------------------------
** 確認曲番号が何曲目かを CDDA_COUNT_program に セット しておく.
** 確認曲の次の曲がなければ、最後の曲だということで、-1 で リターン する.
-----------------------------------------------------------------------------*/
if ( CDDA_nplay < 1 ) {
CDDA_COUNT_program = CDDA_prgptr ;
} else {
CDDA_COUNT_program = CDDA_prgptr - CDDA_nplay + 1 ;
}
if ( CDDA_PLAY_no[CDDA_prgptr] == CDDA_ZERO ) {
return( -1 ) ;
} else {
return( CDDA_COUNT_program ) ;
}
}
}
/************************** プログラムの曲番号を削除 ***************************/
int CDDA_program_data_clear( void )
/*=============================================================================
** プログラムの曲番号を削除する.
**
** < INPUT > : なし
** < OUTPUT > : なし
** < RETURN > : 削除した曲番号(削除できない時は 0)
**
** プログラム登録曲数は、CDDA_TOTAL_program に セット します.
** 残り演奏曲数は、CDDA_REMAIN_program に セット します.
** 確認用の曲が何曲目 (演奏中または演奏開始曲を 1 として) かを
** CDDA_COUNT_program に セット します.
**
** 削除によって更新された確認用の曲番号は、CDDA_NOW_musicno に セット します.
=============================================================================*/
{
int c ;
int delno ;
char playdel ;
char flg ;
char prgclear ;
CDDA_COUNT_program = CDDA_ZERO ;
if ( !CDDA_FLG_tocread ) return( CDDA_ZERO ) ;
if ( CDDA_PLAY_mode != CDDA_SW_PROGRAM ) return( CDDA_ZERO ) ;
/*-----------------------------------------------------------------------------
** 一曲も登録されていない時には、データ削除しない.
-----------------------------------------------------------------------------*/
if ( CDDA_TOTAL_program <= CDDA_ZERO ) return( CDDA_ZERO ) ;
if ( CDDA_REMAIN_program <= CDDA_ZERO ) return( CDDA_ZERO ) ;
/*-----------------------------------------------------------------------------
** プログラムポインタ が クリア されている時には、最後に登録してある曲を削除する.
** 通常は、プログラム確認中の曲を削除する.
-----------------------------------------------------------------------------*/
if ( CDDA_prgptr > CDDA_ZERO ) {
delno = CDDA_PLAY_no[CDDA_prgptr-1] ;
} else {
delno = CDDA_PLAY_no[CDDA_TOTAL_program-1] ;
}
/*
** データ 削除
*/
playdel = CDDA_FALSE ;
if ( CDDA_prgptr > CDDA_ZERO ) {
for ( c=CDDA_prgptr-1; c<CDDA_TOTAL_program; c++ ) {
CDDA_PLAY_no[c] = CDDA_PLAY_no[c+1] ;
}
/*-----------------------------------------------------------------------------
** 今演奏中の曲(かそれよりも前の曲)を削除した場合
-----------------------------------------------------------------------------*/
if ( CDDA_nplay >= CDDA_prgptr && CDDA_nplay > CDDA_ZERO ) {
CDDA_nplay -- ;
playdel = CDDA_TRUE ;
}
/*-----------------------------------------------------------------------------
** 最後の曲を削除した場合(プログラムポインタが最後の曲を指していた時)には、プログラム
** ポインタ を更新しておく.
-----------------------------------------------------------------------------*/
if ( CDDA_prgptr == CDDA_TOTAL_program ) CDDA_prgptr -- ;
} else {
CDDA_PLAY_no[CDDA_TOTAL_program-1] = CDDA_ZERO ;
/*-----------------------------------------------------------------------------
** 今演奏中の曲(かそれよりも前の曲)を削除した場合
-----------------------------------------------------------------------------*/
if ( CDDA_nplay == CDDA_TOTAL_program ) {
CDDA_nplay -- ;
playdel = CDDA_TRUE ;
}
}
/*-----------------------------------------------------------------------------
** 削除後の確認曲番号を CDDA_NOW_musicno に セット しておく.
** 削除後の確認曲番号が何曲目かを CDDA_COUNT_program に セット しておく.
** 演奏中(PAUSE含)の曲を削除した場合には、次の曲の処理をする.
-----------------------------------------------------------------------------*/
prgclear = CDDA_FALSE ;
if ( playdel ) {
/* ↓↓ ★★ DEBUG ★★ ↓↓ */
if ( CDDA_DEBUG ) {
printf( "<CDDA_program_data_clear> " ) ;
printf( "演奏曲削除(status:%xh) : prgptr = %d , nplay = %d",
CDDA_NOW_status,CDDA_prgptr,CDDA_nplay ) ;
printf( " , 削除曲 = %d , 登録曲数(残り) = %d(%d)\n",
delno,CDDA_TOTAL_program,CDDA_REMAIN_program ) ;
}
/* ↑↑ ★★ DEBUG ★★ ↑↑ */
/* ●●● 演奏中(PAUSE含む)の曲を削除した時 ●●● */
CDDA_TOTAL_program -- ;
switch ( CDDA_NOW_status ) {
/*-----------------------------------------------------------------------------
** 今演奏中の曲を削除した場合には、次の曲を演奏する.
** 次の曲がなければ、演奏終了し、プログラム全てを クリア する.
** CDDA_prgptr は、CDDA_next_music() で クリア されることに注意して設定する.
-----------------------------------------------------------------------------*/
case CDDA_STAT_PLAY :
if ( !CDDA_next_music() ) {
CDDA_NOW_musicno = CDDA_NOW_start ;
CDDA_COUNT_program = 1 ;
CDDA_prgptr = CDDA_nplay ;
CDDA_play() ;
} else {
if ( !CDDA_FLG_repeaton ) {
CDDA_music_clear() ; /* 曲管理情報クリア */
CDDA_FLG_nowplay = CDDA_FALSE ;
prgclear = CDDA_TRUE ;
} else { /* リピート処理 */
CDDA_FLG_prgrepeat = CDDA_TRUE ;
}
cdr_mstop( CDDA_INFO_buf.drv ) ;
CDDA_NOW_musicno = CDDA_ZERO ;
CDDA_COUNT_program = CDDA_ZERO ;
}
break ;
/*-----------------------------------------------------------------------------
** 今PAUSE中の曲を削除した場合には、次の曲を演奏開始状態とする.
** 次の曲がなければ、演奏終了し、プログラム全てを クリア する.
** CDDA_prgptr は、CDDA_next_music() で クリア されることに注意して設定する.
-----------------------------------------------------------------------------*/
case CDDA_STAT_PAUSE :
if ( CDDA_ffmusic() ) {
if ( !CDDA_FLG_repeaton ) { /* 終了処理 */
CDDA_music_clear() ; /* 曲管理情報クリア */
CDDA_FLG_nowplay = CDDA_FALSE ;
CDDA_FLG_pause = CDDA_FALSE ;
prgclear = CDDA_TRUE ;
} else { /* リピート処理 */
CDDA_FLG_prgrepeat = CDDA_TRUE ;
}
cdr_mstop( CDDA_INFO_buf.drv ) ;
CDDA_NOW_musicno = CDDA_ZERO ;
CDDA_COUNT_program = CDDA_ZERO ;
} else {
CDDA_COUNT_program = 1 ;
CDDA_prgptr = CDDA_nplay ;
}
}
} else {
if ( CDDA_prgptr > CDDA_ZERO ) {
CDDA_NOW_musicno = CDDA_PLAY_no[CDDA_prgptr-1] ;
if ( CDDA_nplay < 1 ) {
CDDA_COUNT_program = CDDA_prgptr ;
} else {
CDDA_COUNT_program = CDDA_prgptr - CDDA_nplay + 1 ;
}
} else {
/*-----------------------------------------------------------------------------
** プログラムポインタ が クリア されている時には、最後に登録してある曲が削除されるの
** で、そのひとつ前の曲が確認曲となる. ( 2曲以上登録されているかどうか)
-----------------------------------------------------------------------------*/
if ( CDDA_TOTAL_program > 1 ) {
CDDA_NOW_musicno = CDDA_PLAY_no[CDDA_TOTAL_program-2] ;
CDDA_COUNT_program = CDDA_REMAIN_program - 1 ;
} else {
CDDA_NOW_musicno = CDDA_ZERO ;
CDDA_COUNT_program = CDDA_ZERO ;
}
}
}
/*
** 時間情報設定
*/
if ( delno && !prgclear ) {
/*-----------------------------------------------------------------------------
** データ 削除ありの時(プログラム演奏時間の更新)
** ただし、演奏中(PAUSE含)の曲を削除した時に、停止処理をした場合を除く.
-----------------------------------------------------------------------------*/
/* プログラム設定合計時間 */
CDDA_subtime( CDDA_TIME_program.min,
CDDA_TIME_program.sec,
CDDA_TIME_program.frame,
CDDA_TIME_track[delno-1].min,
CDDA_TIME_track[delno-1].sec,
CDDA_TIME_track[delno-1].frame,
&CDDA_TIME_program.min,
&CDDA_TIME_program.sec,
&CDDA_TIME_program.frame ) ;
/*-----------------------------------------------------------------------------
** プログラム登録されていない曲の合計時間を求める.
-----------------------------------------------------------------------------*/
flg = CDDA_TRUE ;
for ( c=0; c<CDDA_TOTAL_program; c++ ) {
if ( CDDA_PLAY_no[c] == delno ) { /* 削除曲の登録はまだある */
flg = CDDA_FALSE ;
break ;
}
}
if ( flg ) {
CDDA_addtime( CDDA_TIME_program2.min,
CDDA_TIME_program2.sec,
CDDA_TIME_program2.frame,
CDDA_TIME_track[delno-1].min,
CDDA_TIME_track[delno-1].sec,
CDDA_TIME_track[delno-1].frame,
&CDDA_TIME_program2.min,
&CDDA_TIME_program2.sec,
&CDDA_TIME_program2.frame ) ;
}
}
/*-----------------------------------------------------------------------------
** プログラム登録曲数を一つ減らす.
-----------------------------------------------------------------------------*/
if ( delno && !playdel ) {
CDDA_TOTAL_program -- ;
CDDA_REMAIN_program -- ;
}
/* 曲内経過時間 */
CDDA_CLOCK_nowtrack.min = CDDA_ZERO ;
CDDA_CLOCK_nowtrack.sec = CDDA_ZERO ;
CDDA_CLOCK_nowtrack.frame = CDDA_ZERO ;
/* 残り時間計算 */
CDDA_program_remaintime() ;
/*-----------------------------------------------------------------------------
** 演奏中(PAUSE含)の曲を削除した時に停止処理をした場合は、時間をクリアしておく.
-----------------------------------------------------------------------------*/
if ( playdel && !CDDA_NOW_musicno ) {
CDDA_CLOCK_program.min = CDDA_ZERO ;
CDDA_CLOCK_program.sec = CDDA_ZERO ;
CDDA_CLOCK_program.frame = CDDA_ZERO ;
}
return( delno ) ;
}
/************************** プログラムの曲番号を追加 ***************************/
int CDDA_program_data_add( int musicno )
/*=============================================================================
** プログラムの曲番号を追加する.
**
** < INPUT > : 曲番号
** < OUTPUT > : なし
** < RETURN > : エラー値(最大登録数99を越えた場合にパラメタエラー値を返す)
**
** プログラム登録曲数は、CDDA_TOTAL_program に セット します.
** 確認用の曲が何曲目 (演奏中または演奏開始曲を 1 として) かを
** CDDA_COUNT_program に セット します.
=============================================================================*/
{
int c ;
char flg ;
CDDA_COUNT_program = CDDA_ZERO ;
if ( !CDDA_FLG_tocread ) return( CDDA_ZERO ) ;
if ( CDDA_PLAY_mode != CDDA_SW_PROGRAM ) return( CDDA_ZERO ) ;
if ( CDDA_TOTAL_program >= CDDA_MAX_TRACK ) return( CDDA_ERR_PARAMETER ) ;
/*-----------------------------------------------------------------------------
** プログラム登録されていない曲の合計時間を求める.
-----------------------------------------------------------------------------*/
flg = CDDA_TRUE ;
for ( c=0; c<CDDA_TOTAL_program; c++ ) {
if ( CDDA_PLAY_no[c] == musicno ) { /* 既に登録済の曲の追加 */
flg = CDDA_FALSE ;
break ;
}
}
if ( flg ) {
CDDA_subtime( CDDA_TIME_program2.min,
CDDA_TIME_program2.sec,
CDDA_TIME_program2.frame,
CDDA_TIME_track[musicno-1].min,
CDDA_TIME_track[musicno-1].sec,
CDDA_TIME_track[musicno-1].frame,
&CDDA_TIME_program2.min,
&CDDA_TIME_program2.sec,
&CDDA_TIME_program2.frame ) ;
}
/*-----------------------------------------------------------------------------
** プログラム曲追加時には、プログラムポインタを リセット しておく.
** (データ削除および続けてデータ追加を行う時のため)
-----------------------------------------------------------------------------*/
CDDA_prgptr = CDDA_ZERO ;
CDDA_PLAY_no[CDDA_TOTAL_program] = musicno ;
/*
** 時間情報設定
*/
CDDA_NOW_musicno = musicno ;
/* プログラム設定合計時間 */
CDDA_addtime( CDDA_TIME_program.min,
CDDA_TIME_program.sec,
CDDA_TIME_program.frame,
CDDA_TIME_track[musicno-1].min,
CDDA_TIME_track[musicno-1].sec,
CDDA_TIME_track[musicno-1].frame,
&CDDA_TIME_program.min,
&CDDA_TIME_program.sec,
&CDDA_TIME_program.frame ) ;
/* 曲内経過時間 */
if ( CDDA_TOTAL_program || CDDA_NOW_status == CDDA_STAT_STOP ) {
/*-----------------------------------------------------------------------------
** 一番最初に登録された曲は、演奏中またはPAUSE中であることがあるので、経過
** 時間を クリア しない.
-----------------------------------------------------------------------------*/
CDDA_CLOCK_nowtrack.min = CDDA_ZERO ;
CDDA_CLOCK_nowtrack.sec = CDDA_ZERO ;
CDDA_CLOCK_nowtrack.frame = CDDA_ZERO ;
}
/* 残り時間計算 */
CDDA_program_remaintime() ;
/*-----------------------------------------------------------------------------
** プログラム登録曲数を一つ増やす.
-----------------------------------------------------------------------------*/
CDDA_TOTAL_program ++ ;
CDDA_REMAIN_program ++ ;
/*-----------------------------------------------------------------------------
** 追加後の確認曲番号が何曲目かを CDDA_COUNT_program に セット しておく.
-----------------------------------------------------------------------------*/
CDDA_COUNT_program = CDDA_REMAIN_program ;
return( CDDA_ERR_NOERROR ) ;
}
/***************************** 演奏初期ステータス取得 ***************************/
void CDDA_initstatus( void )
/*=============================================================================
** 演奏初期化処理時のステータス取得を行う.
**
** < INPUT > : なし
** < OUTPUT > : なし
** < RETURN > : なし
=============================================================================*/
{
int ret ;
/*-----------------------------------------------------------------------------
** CD が入れ換えられた直後の時のために エラー値が真ならば再度 ステータス取得を行う.
-----------------------------------------------------------------------------*/
ret = CDDA_mphase() ;
if ( ret ) {
ret = CDDA_mphase() ;
}
if ( !ret ) {
if ( CDDA_NOW_status ) { /* 演奏中 */
CDDA_FLG_nowplay = CDDA_TRUE ;
CDDA_FLG_cdstop = CDDA_FALSE ;
if ( CDDA_FLG_repeat ) CDDA_FLG_repeaton = CDDA_TRUE ;
CDDA_nplay_check() ;
CDDA_NOW_status = CDDA_STAT_PLAY ;
} else { /* 停止中 */
CDDA_NOW_status = CDDA_STAT_STOP ;
CDDA_NOW_musicno = CDDA_ZERO ;
CDDA_NOW_pause = CDDA_ZERO ;
}
} else {
CDDA_libinit() ; /* NOT READY */
}
}
/****************************** 演奏初期化処理 *****************************/
int CDDA_swinit( void )
/*=============================================================================
** 演奏関係の初期処理を行う.
**
** < INPUT > : なし
** < OUTPUT > : なし
** < RETURN > : エラー値
**
** 当ライブラリ内の使用にあたっては、必ず最初にこの関数をCALLして下さい.
=============================================================================*/
{
int musicno ;
CDDA_TRACK nowtrack ;
if ( !CDDA_FLG_libinit ) CDDA_libinit() ;
CDDA_initstatus() ;
memcpy( (char *)&nowtrack,(char *)&CDDA_CLOCK_nowtrack,
sizeof( CDDA_TRACK ) ) ;
switch ( CDDA_NOW_status ) {
case CDDA_STAT_NOTREADY :
CDDA_libinit() ;
return( CDDA_ERR_NOTREADY ) ;
case CDDA_STAT_STOP :
/*-----------------------------------------------------------------------------
** CD が セット されている時には、TOC を読み込む.
-----------------------------------------------------------------------------*/
if( CDDA_tocread() ) return( CDDA_ERR_NOTREADY ) ;
return( CDDA_status() ) ;
case CDDA_STAT_PAUSE :
return( CDDA_ERR_NOERROR ) ;
case CDDA_STAT_PLAY :
/*-----------------------------------------------------------------------------
** プログラム起動時に、演奏中だった場合には 一旦PAUSEして TOC 情報を取得し、
** その後演奏を続ける.
-----------------------------------------------------------------------------*/
musicno = CDDA_NOW_musicno ;
if( CDDA_tocread() ) return( CDDA_ERR_NOTREADY ) ;
CDDA_nplay = musicno ;
CDDA_set_time_start( musicno ) ;
CDDA_addtime( CDDA_CLOCK_start.min,
CDDA_CLOCK_start.sec,
CDDA_CLOCK_start.frame,
nowtrack.min,
nowtrack.sec,
nowtrack.frame,
&CDDA_CLOCK_start.min,
&CDDA_CLOCK_start.sec,
&CDDA_CLOCK_start.frame ) ;
CDDA_NOW_start = CDDA_INFO_buf.start ;
CDDA_NOW_end = CDDA_INFO_buf.end ;
CDDA_set_time_end( CDDA_NOW_end ) ;
CDDA_timeplay() ;
return( CDDA_status() ) ;
}
}
/******************************* 演奏停止処理 ******************************/
void CDDA_select_stop( int mode )
/*=============================================================================
** STOPキーが入力された時の処理を行う.
**
** < INPUT > : スイッチキー
** < OUTPUT > : なし
** < RETURN > : なし
=============================================================================*/
{
int c ;
switch ( mode ) {
/* ●●● 終了処理 ●●● */
case CDDA_SW_EJECT : /* 強制停止 */
/* case CDDA_SW_EXIT : は CDDA_SW_EJECT と同じ */
/*-----------------------------------------------------------------------------
** CD 回転停止時間(最大値 255sec に)設定
-----------------------------------------------------------------------------*/
cdr_pause( CDDA_INFO_buf.drv ) ;
cdr_stptime( CDDA_INFO_buf.drv,255 ) ;
if ( CDDA_NOW_status == CDDA_STAT_PLAY ||
CDDA_NOW_status == CDDA_STAT_PAUSE )
cdr_continue( CDDA_INFO_buf.drv ) ;
/* ●●● STOP処理 ●●● */
case CDDA_SW_STOP : /* 強制停止 */
/*-----------------------------------------------------------------------------
** プログラムモード時以外は、演奏停止する.
** EJECT/EXIT(終了処理)時には、基本的には演奏を停止する.
** ただし、オプション(CDDA_FLG_stopのこと)として演奏したまま終了できるようにし
** てある.
** 停止指令がきて停止中であることを示すため CDDA_FLG_nowplay を クリア する.
-----------------------------------------------------------------------------*/
CDDA_FLG_nowplay = CDDA_FALSE ;
/*-----------------------------------------------------------------------------
** プログラムモード時には、演奏中にSTOPされた時には、演奏を停止するだけであり、
** 停止状態の時にSTOPされた時には、プログラム設定された曲を クリア する.
-----------------------------------------------------------------------------*/
if ( CDDA_PLAY_mode == CDDA_SW_PROGRAM &&
CDDA_NOW_status == CDDA_STAT_STOP ) {
CDDA_music_clear() ; /* 曲管理情報クリア */
}
/* ●● 演奏停止 ●● */
if ( CDDA_FLG_stop || mode == CDDA_SW_STOP ) CDDA_stop() ;
/* ●● 演奏モードにより処理が異なる ●● */
switch ( CDDA_PLAY_mode ) {
/* ●● SHUFFLE ●● */
case CDDA_SW_SHUFFLE :
/*-----------------------------------------------------------------------------
** シャッフル演奏中にSTOPされた時には、CONTINUEモードに移行し、演奏を停止する.
-----------------------------------------------------------------------------*/
CDDA_PLAY_mode = CDDA_SW_CONTINUE ;
CDDA_nplay = CDDA_ZERO ; /* ポインタ */
for ( c=0; c<CDDA_MAX_TRACK; c++ ) {
if ( c < CDDA_INFO_buf.end )
CDDA_PLAY_no[c] = c+1 ; /* 曲番号 */
else
CDDA_PLAY_no[c] = CDDA_ZERO ; /* クリア */
}
CDDA_NOW_end = CDDA_INFO_buf.end ;
break ;
/* ●● PROGRAM ●● */
case CDDA_SW_PROGRAM :
/*-----------------------------------------------------------------------------
** プログラム設定曲の確認をするための プログラムポインタ を クリア しておく.
-----------------------------------------------------------------------------*/
CDDA_prgptr = CDDA_ZERO ;
break ;
/* ●● SINGLE / CONTINUE ●● */
case CDDA_SW_SINGLE :
case CDDA_SW_CONTINUE :
CDDA_nplay = CDDA_ZERO ; /* ポインタ */
CDDA_NOW_end = CDDA_INFO_buf.end ;
}
}
}
/******************************* 曲選択処理 ********************************/
int CDDA_select_music( int no )
/*=============================================================================
** 曲が選択された時の処理を行う.
**
** < INPUT > : 曲番号
** < OUTPUT > : なし
** < RETURN > : エラー値
=============================================================================*/
{
int c ;
if ( CDDA_PLAY_mode == CDDA_SW_PROGRAM ) {
/*-----------------------------------------------------------------------------
** プログラムモード時には、曲の追加のみ行う.
-----------------------------------------------------------------------------*/
return( CDDA_program_data_add( no ) ) ;
} else {
/*-----------------------------------------------------------------------------
** 指定された曲番号を演奏開始曲とする.
** また、曲番号が指定された時は、プログラムモード時以外は、CONTINUEモードかSINGLE
** モードの場合だけであるので、演奏ポインタ を更新しておく.
** CONTINUEモードかSINGLEモードの時以外(プログラムモードを除く)は、CONTINUEモードに移行
** してしまう.
-----------------------------------------------------------------------------*/
CDDA_NOW_start = no ;
CDDA_nplay = no ; /* ポインタ */
/*-----------------------------------------------------------------------------
** 他のモードから移行された時のために、演奏曲の格納をし直しておく.
-----------------------------------------------------------------------------*/
for ( c=0; c<CDDA_MAX_TRACK; c++ ) {
if ( c < CDDA_INFO_buf.end )
CDDA_PLAY_no[c] = c+1 ; /* 曲番号 */
else
CDDA_PLAY_no[c] = CDDA_ZERO ; /* クリア */
}
switch ( CDDA_PLAY_mode ) {
case CDDA_SW_SHUFFLE :
/*-----------------------------------------------------------------------------
** シャッフル演奏時には、CONTINUEモードに移行し、最後の曲まで演奏するようにする.
-----------------------------------------------------------------------------*/
CDDA_PLAY_mode = CDDA_SW_CONTINUE ;
case CDDA_SW_CONTINUE :
CDDA_NOW_end = CDDA_INFO_buf.end ;
break ;
case CDDA_SW_SINGLE :
/*-----------------------------------------------------------------------------
** SINGLEモード時には、演奏開始曲だけを演奏するように終了曲を設定する.
-----------------------------------------------------------------------------*/
CDDA_NOW_end = no ;
}
}
/*-----------------------------------------------------------------------------
** PAUSE中には、指定された曲から演奏開始できるように時間情報を設定しておく.
** 演奏はしないで、PAUSE状態を保持する. ただし、指定された曲の頭から演奏開始
** できるようにする.
**
** PAUSE中でなければ、指定された曲番号から演奏を開始する.
-----------------------------------------------------------------------------*/
if ( CDDA_NOW_status == CDDA_STAT_PAUSE ) {
/*
** PAUSE中ならば時間設定するだけ
*/
CDDA_FLG_pauseplay = CDDA_TRUE ;
CDDA_NOW_musicno = CDDA_NOW_pause = no ;
/*
** 演奏時間の指定
*/
CDDA_set_time_start( CDDA_NOW_start ) ; /* 演奏開始曲データ設定 */
CDDA_set_time_end( CDDA_NOW_end ) ; /* 演奏終了曲データ設定 */
/*
** 現在の曲内経過時間
*/
CDDA_CLOCK_nowtrack.min = CDDA_ZERO ;
CDDA_CLOCK_nowtrack.sec = CDDA_ZERO ;
CDDA_CLOCK_nowtrack.frame = CDDA_ZERO ;
memcpy( (char *)&CDDA_CLOCK_pause,(char *)&CDDA_CLOCK_nowtrack,
sizeof( CDDA_TRACK ) ) ;
/*
** 現在の残り時間
*/
CDDA_remaintime() ;
return( CDDA_seek() ) ;
} else {
return( CDDA_play() ) ;
}
}
/******************************* モード選択処理 ******************************/
void CDDA_select_mode( int mode )
/*=============================================================================
** 演奏モードが選択された時の処理を行う.
**
** < INPUT > : 演奏モード
** < OUTPUT > : なし
** < RETURN > : なし
=============================================================================*/
{
int c ;
/*-----------------------------------------------------------------------------
** 各モードは、他のモードから移行してきた時だけ、モード毎の処理を行う.
-----------------------------------------------------------------------------*/
switch ( mode ) {
case CDDA_SW_PROGRAM :
if ( CDDA_PLAY_mode != CDDA_SW_PROGRAM ) {
CDDA_PLAY_mode = mode ;
/*-----------------------------------------------------------------------------
** 演奏曲番号 および プログラム曲の合計時間の クリア を行う.
-----------------------------------------------------------------------------*/
CDDA_music_clear() ; /* 曲管理情報クリア */
/*-----------------------------------------------------------------------------
** プログラムモード移行時に、演奏中またはPAUSE中ならば、その曲をプログラム登録して
** しまう.
** それ以外は、クリア 作業を行う.
-----------------------------------------------------------------------------*/
if ( CDDA_NOW_status == CDDA_STAT_PLAY ||
CDDA_NOW_status == CDDA_STAT_PAUSE ) {
CDDA_nplay = 1 ;
CDDA_NOW_start = CDDA_NOW_end = CDDA_NOW_musicno ;
CDDA_set_time_start( CDDA_NOW_start ) ; /* 演奏開始 */
/*-----------------------------------------------------------------------------
** PAUSE解除時に対応するための時間設定をする.
-----------------------------------------------------------------------------*/
CDDA_addtime( CDDA_CLOCK_start.min,
CDDA_CLOCK_start.sec,
CDDA_CLOCK_start.frame,
CDDA_CLOCK_nowtrack.min,
CDDA_CLOCK_nowtrack.sec,
CDDA_CLOCK_nowtrack.frame,
&CDDA_CLOCK_start.min,
&CDDA_CLOCK_start.sec,
&CDDA_CLOCK_start.frame ) ;
CDDA_set_time_end( CDDA_NOW_end ) ; /* 演奏終了 */
CDDA_program_data_add( CDDA_NOW_musicno ) ;
}
}
break ;
case CDDA_SW_CONTINUE :
case CDDA_SW_SINGLE :
if ( CDDA_PLAY_mode == mode ) break ;
CDDA_PLAY_mode = mode ;
/*-----------------------------------------------------------------------------
** CONTINUEモード,SINGLEモード時には、演奏中またはPAUSE中であれば、その曲を演奏
** 開始曲とする. そうでなければ、最初の曲を開始曲とする.
-----------------------------------------------------------------------------*/
if ( CDDA_NOW_status == CDDA_STAT_PLAY ||
CDDA_NOW_status == CDDA_STAT_PAUSE ) {
CDDA_NOW_start = CDDA_NOW_musicno ;
} else if ( CDDA_NOW_status == CDDA_STAT_STOP ) {
CDDA_NOW_start = CDDA_PLAY_no[0] ;
}
/*-----------------------------------------------------------------------------
** CONTINUEモード時でも、status取得後のチェックのために演奏終了曲を開始曲として
** おく.
-----------------------------------------------------------------------------*/
CDDA_NOW_end = CDDA_NOW_start ;
CDDA_nplay = CDDA_NOW_musicno ; /* ポインタ */
CDDA_prgptr = CDDA_ZERO ;
/*-----------------------------------------------------------------------------
** 他のモードから移行された時のために、演奏曲の格納をし直しておく.
-----------------------------------------------------------------------------*/
for ( c=0; c<CDDA_MAX_TRACK; c++ ) {
if ( c < CDDA_INFO_buf.end )
CDDA_PLAY_no[c] = c+1 ; /* 曲番号 */
else
CDDA_PLAY_no[c] = CDDA_ZERO ; /* クリア */
}
break ;
case CDDA_SW_REPEAT :
/*-----------------------------------------------------------------------------
** リピート指定は、停止時にリピート処理を行うための フラグ と リピート指定があったとい
** う フラグ がある.
** これは、各演奏モードにおいて、演奏状態をチェックする場合に意味を持つ.
**
** リピート指定時もしくは、リピート指定後演奏状態またはPAUSE状態であれば、リピートを
** 有効にするという意味で、CDDA_FLG_repeaton を真値とする.
-----------------------------------------------------------------------------*/
if ( CDDA_FLG_repeat ) {
CDDA_FLG_repeat = CDDA_FALSE ;
CDDA_FLG_repeaton = CDDA_FALSE ;
} else {
CDDA_FLG_repeat = CDDA_TRUE ;
CDDA_FLG_repeaton = CDDA_FALSE ;
if ( CDDA_NOW_status == CDDA_STAT_PLAY ||
CDDA_NOW_status == CDDA_STAT_PAUSE )
CDDA_FLG_repeaton = CDDA_TRUE ;
}
}
}
/******************************* 演奏選択処理 ******************************/
int CDDA_select_play( void )
/*=============================================================================
** 演奏が選択された時の処理を行う.
**
** < INPUT > : なし
** < OUTPUT > : なし
** < RETURN > : なし
**
** 演奏中に演奏命令が来ても、無効とする.
** ただし、シャッフル演奏時には、シャッフル演奏を無効とし、CONTINUEモードに移行する.
** PAUSE中であれば、PAUSEの解除を行う.
=============================================================================*/
{
int ret ;
int c ;
ret = CDDA_ERR_NOERROR ;
if ( CDDA_PLAY_mode == CDDA_SW_SHUFFLE ) {
/*-----------------------------------------------------------------------------
** 停止中または演奏中の状態が、シャッフルモードによるものならば、CONTINUEモードに移行
** する. そのために、曲番号の管理領域を リセット しておく.
-----------------------------------------------------------------------------*/
switch ( CDDA_NOW_status ) {
case CDDA_STAT_STOP :
case CDDA_STAT_PLAY :
for ( c=0; c<CDDA_MAX_TRACK; c++ ) {
if ( c < CDDA_INFO_buf.end )
CDDA_PLAY_no[c] = c+1 ; /* 曲番号 */
else
CDDA_PLAY_no[c] = CDDA_ZERO ; /* クリア */
}
}
}
/* ●●● 演奏モードにより処理が異なる ●●● */
switch ( CDDA_PLAY_mode ) {
case CDDA_SW_PROGRAM :
/*-----------------------------------------------------------------------------
** プログラムモード時には、停止中であれば、プログラム登録してある曲のうち 演奏済で
** ない曲から演奏を開始する.
-----------------------------------------------------------------------------*/
switch ( CDDA_NOW_status ) {
case CDDA_STAT_STOP :
if ( CDDA_nplay > CDDA_ZERO ) {
CDDA_NOW_start = CDDA_PLAY_no[CDDA_nplay-1] ;
CDDA_NOW_end = CDDA_PLAY_no[CDDA_nplay-1] ;
} else {
CDDA_NOW_start = CDDA_NOW_end = CDDA_PLAY_no[CDDA_ZERO] ;
}
ret = CDDA_play() ;
break ;
case CDDA_STAT_PAUSE :
/*-----------------------------------------------------------------------------
** PAUSE中であれば、PAUSEを解除する.
-----------------------------------------------------------------------------*/
CDDA_FLG_pauseplay = CDDA_TRUE ;
ret = CDDA_pause() ;
break ;
case CDDA_STAT_PLAY :
/*-----------------------------------------------------------------------------
** 演奏中は、無視し、演奏中である旨の エラー値 を返す.
-----------------------------------------------------------------------------*/
ret = CDDA_ERR_NOWPLAY ;
}
break ;
/*-----------------------------------------------------------------------------
** ●●● プログラムモード以外 ●●●
-----------------------------------------------------------------------------*/
default :
/*-----------------------------------------------------------------------------
** プログラムモード以外では、停止中であれば、最初の曲から演奏を行う.
-----------------------------------------------------------------------------*/
switch ( CDDA_NOW_status ) {
case CDDA_STAT_STOP :
CDDA_nplay = CDDA_ZERO ; /* ポインタ */
/*-----------------------------------------------------------------------------
** シャッフル状態のままならば、CONTINUEモードに移行し演奏するようにする.
-----------------------------------------------------------------------------*/
if ( CDDA_PLAY_mode == CDDA_SW_SHUFFLE ) {
CDDA_PLAY_mode = CDDA_SW_CONTINUE ;
}
CDDA_NOW_start = CDDA_PLAY_no[CDDA_ZERO] ;
CDDA_NOW_end = CDDA_NOW_start ;
if ( CDDA_PLAY_mode == CDDA_SW_CONTINUE )
CDDA_NOW_end = CDDA_INFO_buf.end ;
ret = CDDA_play() ;
break ;
case CDDA_STAT_PAUSE :
/*-----------------------------------------------------------------------------
** PAUSE中であれば、PAUSEを解除する.
-----------------------------------------------------------------------------*/
ret = CDDA_pause() ;
break ;
case CDDA_STAT_PLAY :
/*-----------------------------------------------------------------------------
** 演奏中は、無視し、演奏中である旨の エラー値 を返す.
** ただし、シャッフル演奏中ならば、CONTINUEモードに移行する.
-----------------------------------------------------------------------------*/
if ( CDDA_PLAY_mode == CDDA_SW_SHUFFLE ) {
CDDA_PLAY_mode = CDDA_SW_CONTINUE ;
CDDA_NOW_start = CDDA_NOW_musicno ;
CDDA_nplay = CDDA_NOW_musicno ; /* ポインタ */
/* モード移行時のチェックのため */
/*-----------------------------------------------------------------------------
** シャッフル演奏時は、一曲演奏なので、CONTINUEモードに移行した時の演奏状態チェックの
** ために、演奏終了曲を今演奏中の曲番号としておく.
-----------------------------------------------------------------------------*/
ret = CDDA_ERR_NOERROR ;
} else {
/*-----------------------------------------------------------------------------
** 演奏中は、無視し、演奏中である旨の エラー値 を返す.
-----------------------------------------------------------------------------*/
ret = CDDA_ERR_NOWPLAY ;
}
break ;
default :
CDDA_libinit() ;
ret = CDDA_ERR_NOTREADY ;
break ;
}
}
return( ret ) ;
}
/***************************** シャッフル演奏選択処理 ***************************/
int CDDA_select_shuffle( void )
/*=============================================================================
** シャッフル演奏が選択された時の処理を行う.
**
** < INPUT > : なし
** < OUTPUT > : なし
** < RETURN > : なし
**
** あらたにシャッフルしなおして、演奏を開始する.
=============================================================================*/
{
int ret ;
ret = CDDA_ERR_NOERROR ;
/*-----------------------------------------------------------------------------
** シャッフル演奏を開始させようとして、演奏曲がなかった場合には、音楽なしのエラー値
** を返す.
** PAUSE中であれば、シャッフル演奏をする準備だけし、PAUSE状態を保持する.
-----------------------------------------------------------------------------*/
CDDA_PLAY_mode = CDDA_SW_SHUFFLE ;
CDDA_FLG_shuffleinit = CDDA_TRUE ;
if ( !CDDA_shuffle( &CDDA_NOW_start ) ) {
CDDA_NOW_end = CDDA_NOW_start ;
if ( CDDA_FLG_pause ) { /* PAUSE中 */
CDDA_FLG_pauseplay = CDDA_TRUE ;
if ( CDDA_FLG_ffrew && CDDA_FLG_ffrewpause ) {
ret = CDDA_play() ;
} else { /* 時間設定するだけ */
CDDA_set_time_start( CDDA_NOW_start ) ;
CDDA_set_time_end( CDDA_NOW_end ) ;
}
} else {
ret = CDDA_play() ;
}
} else {
if ( CDDA_NOW_status == CDDA_STAT_NOTREADY )
ret = CDDA_ERR_NOTREADY ;
else
ret = CDDA_ERR_NOMUSIC ;
}
return( ret ) ;
}
/******************************* プログラム操作処理 ***************************/
int CDDA_select_program( int mode )
/*=============================================================================
** プログラムによる曲の確認/削除の処理を行う.
**
** < INPUT > : プログラムスイッチ
** < OUTPUT > : なし
** < RETURN > : 曲番号
=============================================================================*/
{
switch ( mode ) {
/* ●● プログラム確認 ●● */
case CDDA_SW_PRG_CHECK :
CDDA_COUNT_program = CDDA_ZERO ;
if ( CDDA_PLAY_mode != CDDA_SW_PROGRAM ) return( CDDA_ZERO ) ;
if ( CDDA_NOW_status == CDDA_STAT_NOTREADY )
return( CDDA_ZERO ) ;
return( CDDA_program_data_check() ) ;
/* ●● プログラム1曲削除 ●● */
case CDDA_SW_PRG_CLEAR :
CDDA_COUNT_program = CDDA_ZERO ;
if ( CDDA_PLAY_mode != CDDA_SW_PROGRAM ) return( CDDA_ZERO ) ;
if ( CDDA_NOW_status == CDDA_STAT_NOTREADY )
return( CDDA_ZERO ) ;
return( CDDA_program_data_clear() ) ;
/* ●● プログラム確認/削除ポインタのクリア ●● */
case CDDA_SW_PRG_TOP :
/*-----------------------------------------------------------------------------
** プログラムポインタ を クリア する.
-----------------------------------------------------------------------------*/
CDDA_prgptr = CDDA_ZERO ;
return( CDDA_ERR_NOERROR ) ;
}
}
/******************************* 演奏スイッチ処理 ******************************/
int CDDA_switch( int mode )
/*=============================================================================
** CDプレーヤのインターフェース(スイッチ相当)処理を行う.
**
** < INPUT > : モード(スイッチ) か 曲番号
** < OUTPUT > : なし
** < RETURN > : エラー値( プログラム時には 曲番号 , 終了時は 0 )
=============================================================================*/
{
int ret ;
if ( !CDDA_FLG_libinit ) CDDA_libinit() ;
switch ( mode ) {
/* ●● 初期処理 ●● */
case CDDA_SW_INIT :
return( CDDA_swinit() ) ;
/* ●● プログラムポインタのクリア ●● */
case CDDA_SW_PRG_TOP :
CDDA_prgptr = CDDA_ZERO ;
return( CDDA_ERR_NOERROR ) ;
/* ●● ステータス取得 ●● */
case CDDA_SW_STATUS :
return( CDDA_status() ) ;
/* ●● ステータスチェック ●● */
default :
if ( !CDDA_FLG_ffrew ) { /* FF/REW中でなければ... */
ret = CDDA_status() ;
if ( ret ) return( ret ) ;
}
}
/*-----------------------------------------------------------------------------
** フラグクリア処理
-----------------------------------------------------------------------------*/
switch ( mode ) {
case CDDA_SW_FFMUSIC :
case CDDA_SW_REWMUSIC :
case CDDA_SW_FFTIME :
case CDDA_SW_REWTIME :
/*-----------------------------------------------------------------------------
** 先送り/後戻り処理は、演奏中かPAUSE中以外は、無効とする.
-----------------------------------------------------------------------------*/
if ( CDDA_NOW_status != CDDA_STAT_PLAY &&
CDDA_NOW_status != CDDA_STAT_PAUSE )
return( CDDA_ERR_PARAMETER ) ;
case CDDA_SW_PAUSE :
case CDDA_SW_SHUFFLE :
break ;
default :
/*-----------------------------------------------------------------------------
** 先送り/後戻り時に、最後に スイッチ を放したという命令がこなくても他の スイッチ が
** 押された時には、先送り/後戻りの終了とする.
**
** ただし、PAUSE / SHUFFLE スイッチ は、FF/REW 中でも有効とする.
-----------------------------------------------------------------------------*/
if ( CDDA_FLG_ffrew && CDDA_FLG_ffrewpause ) {
/* FF/REW中でPAUSEした時 */
ret = CDDA_pause() ;
}
CDDA_FLG_ffrew = CDDA_FALSE ;
CDDA_FLG_ffrewpause = CDDA_FALSE ;
}
/*-----------------------------------------------------------------------------
** 演奏終了処理
-----------------------------------------------------------------------------*/
switch ( mode ) {
case CDDA_SW_EJECT :
/* case CDDA_SW_EXIT : は CDDA_SW_EJECT と同じ */
case CDDA_SW_STOP :
CDDA_select_stop( mode ) ;
return( ret ) ;
}
/* ●●●●● 演奏スイッチ処理 ●●●●● */
if ( mode > CDDA_MAX_TRACK ) {
/*-----------------------------------------------------------------------------
** 演奏処理
-----------------------------------------------------------------------------*/
switch ( mode ) {
/* ●● TOC 読み込み ●● */
case CDDA_SW_TOCREAD :
if ( CDDA_tocread() ) return( CDDA_ERR_NOTREADY ) ;
return( CDDA_ERR_NOERROR ) ;
/* ●● PAUSE ●● */
case CDDA_SW_PAUSE :
/*-----------------------------------------------------------------------------
** FF/REW の スイッチ ON の時には、必ず停止状態とするために、現在のPAUSE状態が
** FF/REW によるものか元々PAUSE状態だっものかを見分ける必要がある.
** そのために ffrewpause フラグ を使用している.
-----------------------------------------------------------------------------*/
if ( CDDA_FLG_ffrew ) { /* FF/REW中 */
CDDA_FLG_ffrew = CDDA_FALSE ;
if ( CDDA_FLG_ffrewpause ) { /* FF/REW中でPAUSEした時 */
CDDA_FLG_ffrewpause = CDDA_FALSE ;
} else { /* 元々PAUSE中だった時 */
ret = CDDA_pause() ;
}
} else { /* 通常 */
ret = CDDA_pause() ;
}
return( ret ) ;
/* ●● PLAY ●● */
case CDDA_SW_PLAY :
return( CDDA_select_play() ) ;
/* ●● SHUFFLE ●● */
case CDDA_SW_SHUFFLE :
CDDA_FLG_ffrew = CDDA_FALSE ;
CDDA_FLG_ffrewpause = CDDA_FALSE ;
return( CDDA_select_shuffle() ) ;
}
/*-----------------------------------------------------------------------------
** プログラム処理
-----------------------------------------------------------------------------*/
switch ( mode ) {
case CDDA_SW_PRG_CHECK :
case CDDA_SW_PRG_CLEAR :
/* case CDDA_SW_PRG_TOP : status を 取得する必要なしのため,
先頭にて処理する. */
return( CDDA_select_program( mode ) ) ;
}
/*-----------------------------------------------------------------------------
** 先送り/後戻り時の前後処理
-----------------------------------------------------------------------------*/
switch ( mode ) {
case CDDA_SW_FFMUSIC :
case CDDA_SW_REWMUSIC :
case CDDA_SW_FFTIME :
case CDDA_SW_REWTIME :
/*-----------------------------------------------------------------------------
** FF/REW 時には、必ずPAUSE状態でなければならないため、FF/REW 開始時/終了時
** には、PAUSE処理をしておく必要がある.
-----------------------------------------------------------------------------*/
if ( CDDA_NOW_status == CDDA_STAT_PLAY ||
CDDA_NOW_status == CDDA_STAT_PAUSE ) {
if ( !CDDA_FLG_ffrew ) { /* FF/REW中でない時 */
CDDA_FLG_ffrew = CDDA_TRUE ;
CDDA_FLG_ffrewpause = CDDA_FALSE ;
if ( !CDDA_FLG_pause ) { /* PAUSE中でない時 */
CDDA_FLG_ffrewpause = CDDA_TRUE ;
ret = CDDA_pause() ;
}
}
} else {
CDDA_FLG_ffrew = CDDA_FALSE ;
CDDA_FLG_ffrewpause = CDDA_FALSE ;
}
break ;
}
/*-----------------------------------------------------------------------------
** 先送り/後戻り処理( return )
-----------------------------------------------------------------------------*/
switch ( mode ) {
case CDDA_SW_FFMUSIC :
return( CDDA_ffmusic() ) ;
case CDDA_SW_REWMUSIC :
return( CDDA_rewmusic() ) ;
case CDDA_SW_FFTIME :
return( CDDA_fftime() ) ;
case CDDA_SW_REWTIME :
return( CDDA_rewtime() ) ;
}
/*-----------------------------------------------------------------------------
** モード設定
-----------------------------------------------------------------------------*/
switch ( mode ) {
case CDDA_SW_PROGRAM :
case CDDA_SW_CONTINUE :
case CDDA_SW_SINGLE :
case CDDA_SW_REPEAT :
CDDA_select_mode( mode ) ;
return( CDDA_ERR_NOERROR ) ;
}
}
/*-----------------------------------------------------------------------------
** 曲番号指定による演奏
-----------------------------------------------------------------------------*/
if ( mode < CDDA_INFO_buf.start || mode > CDDA_INFO_buf.end )
return( CDDA_ERR_PARAMETER ) ;
CDDA_FLG_ffrew = CDDA_FALSE ;
CDDA_FLG_ffrewpause = CDDA_FALSE ;
return( CDDA_select_music( mode ) ) ;
}
/******************************* 演奏モード取得 ******************************/
int CDDA_get_playmode( void )
/*=============================================================================
** 現在の演奏モードを取得する.
**
** < INPUT > : なし
** < OUTPUT > : なし
** < RETURN > : 演奏モード値
=============================================================================*/
{
return( CDDA_PLAY_mode ) ;
}
/*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
#undef _CDDA_LIB
/*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
/******************************* デバッグ用 ********************************/
void CDDA_debug_dispmsg( int errno )
/*=============================================================================
** デバッグ用にメッセージIDに対応したメッセージを出力する.
**
** < INPUT > : エラー値
** < OUTPUT > : なし
** < RETURN > : なし
=============================================================================*/
{
char *CDDA_ERR_msg[] = {
"正常終了.", /* 000(0x000) */
"CDがセットされていません.", /* 001(0x001) */
"パラメタに誤りがあります.", /* 002(0x002) */
"CDドライブが接続されていません.", /* 004(0x004) */
"コマンドが異常終了しました.", /* 008(0x008) */
"メディアエラー.", /* 016(0x010) */
"ハードエラー.", /* 032(0x020) */
"パリティエラー.", /* 064(0x040) */
"メディアが交換されてます.", /* 128(0x080) */
"デバイス番号に誤りがあります.", /* 256(0x100) */
"セクタ長が違います.", /* 257(0x101) */
"音楽演奏中です.", /* 258(0x102) */
"一時停止中です.", /* 260(0x104) */
"一時停止状態ではありません.", /* 264(0x108) */
"音楽データがありません.", /* 272(0x110) */
"繰り返し演奏を開始しました.", /* 288(0x120) */
"該当メッセージなし." /* ---(0x---) */
} ;
char *CDDA_STATUS_msg[] = {
"CDがセットされていません.",
"停止中です.",
"演奏中です.",
"一時停止中です."
} ;
int c, chk, no ;
int nomsg = 16 ;
chk = 0x0001 ;
no = 0 ;
for ( c=0; c<8; c++ ) {
if ( ((errno & 0x00ff) & chk) == chk ) no = c + 1 ;
chk <<= 1 ;
}
if ( errno > 255 ) no += 9 ;
if ( errno != 0 && no == 0 ) no = nomsg ;
if ( no < 0 || no > nomsg ) no = nomsg ;
printf( "CDDA DEBUG MSG (%04xh) : %s\n",errno,CDDA_ERR_msg[no] ) ;
no = CDDA_NOW_status ;
if ( no < 0 ) {
no = 0 ;
} else {
no ++ ;
}
printf( "Now status (%d) : %s\n",CDDA_NOW_status,CDDA_STATUS_msg[no] ) ;
}